﻿/*!
CUSTOM CSS hier rein
 */

/*!

IDs

 */


div#SelectedArticleFeatures {
    margin-top: 1rem;
}

.dropdown-menu-max-height {
    max-height: 500px;
    overflow-y: auto;
}

/*!

Klassen

 */

.navbar {
    margin-bottom: 10px;
}


.form-signin {
    width: 100%;
    max-width: 330px;
    padding: 15px;
    margin: 0 auto;
}

/* ==== Gast-Header Login (theme-agnostisch) ==================================== */
/* Eingabefeld mit Icon INNEN (kein input-group-Kasten davor) */
.login-field {
    position: relative;
}

.login-field__icon {
    position: absolute;
    left: .85rem;
    top: 50%;
    transform: translateY(-50%);
    color: #adb5bd;
    font-size: .95rem;
    pointer-events: none;
}

.login-field__input {
    padding-left: 2.4rem;
    border-radius: 8px;
}

/* Feste Feldbreite fuer den inline Desktop-Direktlogin */
.login-desktop-field {
    width: 190px;
}

/* Sekundaeraktionen (Passwort vergessen / Registrieren / Praesentationslogin) als Pill-Chips */
.login-chips {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .4rem;
}

.login-chip {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    font-size: .78rem;
    line-height: 1;
    padding: .35rem .7rem;
    border-radius: 50rem;
    background-color: #f1f3f5;
    white-space: nowrap;
    transition: background-color .15s ease-in-out;
}

.login-chip:hover,
.login-chip:focus-visible {
    background-color: #e2e6ea;
    text-decoration: none;
}

.login-chip:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 2px;
}

.card-img-top {
    max-height: 30vh;
    width: 100%;
    aspect-ratio: 1/1;
    object-fit: scale-down;
}

.CarouselArrow {
    background-color: black;
}

.card-title {
    padding: .75rem 1.25rem;
    margin-bottom: 0;
}

.imagewrapper {
    width: 100%;
    position: relative;
    display: inline-block;
}

img.FeatureImage {
    height: 1.4rem;
}

img.FeatureValueImage {
    max-height: 2rem;
}

.blockquote-spezial {
    font-size: 80%;
    color: #6c757d
}

.btn-hover-spezial:hover {
    background-color: #e2e6ea;
    border-color: #dae0e5
}

.i-spezial:hover {
    color: #007bff;
}

.custom-card-hover:hover {
    transform: scale(1.01);
    box-shadow: 0 10px 20px rgba(0, 0, 0, .08), 0 4px 8px rgba(0, 0, 0, .06);
}

/* ==== Willkommen-/Hero-Karte: moderne Feature-Darstellung =========================
   Getoente Icon-Chips + luftige Headline. Icon-/Akzentfarben kommen aus BS-Utilities
   (text-success/bg-success im Markup) und bleiben damit theme-aware. */
.hero-feature-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 64px;
    border-radius: 16px;
    font-size: 1.6rem;
    background-color: rgba(0, 154, 62, .10); /* dezenter Gruen-Tint (Vomberg). fichtner: NICHT hier aendern, sondern in "Fichtner Standard.css" ueberschreiben (Theme-CSS, !important), damit diese geteilte Datei branchgleich bleibt */
    transition: background-color .25s ease, transform .25s ease;
}

.hero-eyebrow {
    text-transform: uppercase;
    letter-spacing: .1em;
    font-size: .8rem;
    font-weight: 700;
}

.hero-accent {
    width: 64px;
    height: 4px;
    border-radius: 2px;
}

/* Feature-Card: dezent gerahmt in Ruhe, edler Lift beim Hover (kein Zoom) */
.hero-feature-card {
    background-color: #fff;
    border: 1px solid #edf0f2;
    border-radius: 14px;
    transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
}

.hero-feature-card:hover {
    transform: translateY(-6px);
    border-color: transparent;
    box-shadow: 0 14px 32px rgba(0, 44, 118, .10), 0 4px 10px rgba(0, 0, 0, .05);
}

.hero-feature-card:hover .hero-feature-chip {
    transform: scale(1.08);
    background-color: rgba(0, 154, 62, .18);
}

/* Abschliessendes CTA-/Ansprechpartner-Panel: dezent getoent, abgesetzt */
.hero-cta-panel {
    background-color: #f6f8fb;
    border-radius: 14px;
}

.event-banner-container {
    overflow: hidden;
    height: 160px;
}

@media (min-width: 768px) {
    .event-banner-container {
        height: 220px;
    }
}

.event-banner-container img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.event-banner-container .carousel,
.event-banner-container .carousel .mb-2,
.event-banner-container .carousel-item {
    margin: 0 !important;
    padding: 0 !important;
    height: 100%;
}

.event-banner-container .carousel-indicators {
    display: none;
}

.event-banner-container .carousel.d-none:only-child {
    display: block !important;
}

/* ==== Willkommen-/Hero-Karte: moderne Feature-Darstellung =========================
   Getoente Icon-Chips + luftige Headline. Icon-/Akzentfarben kommen aus BS-Utilities
   (text-success/bg-success im Markup) und bleiben damit theme-aware. */
.hero-feature-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 64px;
    border-radius: 16px;
    font-size: 1.6rem;
    background-color: rgba(0, 154, 62, .10); /* dezenter Gruen-Tint (Vomberg). fichtner: NICHT hier aendern, sondern in "Fichtner Standard.css" ueberschreiben (Theme-CSS, !important), damit diese geteilte Datei branchgleich bleibt */
    transition: background-color .25s ease, transform .25s ease;
}

.hero-eyebrow {
    text-transform: uppercase;
    letter-spacing: .1em;
    font-size: .8rem;
    font-weight: 700;
}

.hero-accent {
    width: 64px;
    height: 4px;
    border-radius: 2px;
}

/* Feature-Card: dezent gerahmt in Ruhe, edler Lift beim Hover (kein Zoom) */
.hero-feature-card {
    background-color: #fff;
    border: 1px solid #edf0f2;
    border-radius: 14px;
    transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
}

.hero-feature-card:hover {
    transform: translateY(-6px);
    border-color: transparent;
    box-shadow: 0 14px 32px rgba(0, 44, 118, .10), 0 4px 10px rgba(0, 0, 0, .05);
}

.hero-feature-card:hover .hero-feature-chip {
    transform: scale(1.08);
    background-color: rgba(0, 154, 62, .18);
}

/* Abschliessendes CTA-/Ansprechpartner-Panel: dezent getoent, abgesetzt */
.hero-cta-panel {
    background-color: #f6f8fb;
    border-radius: 14px;
}

.event-banner-container {
    overflow: hidden;
    height: 160px;
}

@media (min-width: 768px) {
    .event-banner-container {
        height: 220px;
    }
}

.event-banner-container img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.event-banner-container .carousel,
.event-banner-container .carousel .mb-2,
.event-banner-container .carousel-item {
    margin: 0 !important;
    padding: 0 !important;
    height: 100%;
}

.event-banner-container .carousel-indicators {
    display: none;
}

.event-banner-container .carousel.d-none:only-child {
    display: block !important;
}

.custom-image-hover:hover {
    opacity: 0.8;
}

/* ==== Startseiten-Hero-Slider (theme-agnostisch) ==================================
   Rahmt den Home-Slider ein und deckelt die Anzeigehoehe per festem Seitenverhaeltnis
   + object-fit:cover. Dadurch wird das Bild sauber zugeschnitten statt gestreckt
   (kein w-100-Upscaling mehr) und die Sektion wirkt wertiger, ohne "riesig" zu werden.
   Bilddaten bleiben backend-gepflegt (ResourceGroup 50 Desktop / 51 Mobile). */
.home-hero {
    border-radius: 15px;
    overflow: hidden;
    box-shadow: 0 1rem 3rem rgba(0, 0, 0, .175); /* = Bootstrap shadow-lg, passend zur Willkommen-Card */
}

.home-hero .imagewrapper {
    display: block; /* ueberschreibt inline-block der Basisklasse -> kein Baseline-Spalt (weisser Ueberhang) */
    border-radius: inherit;
    overflow: hidden;
}

/* Feste Buehne: Bild fuellt den Rahmen via cover, keine Verzerrung.
   24/5 (= 4.8:1) passt zum realen Bannerformat (z.B. 1920x400). */
.home-hero .carousel-item {
    aspect-ratio: 24 / 5;
}

.home-hero__img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Mobile-Slider (ResourceGroup 51): hoeheres Format, hier greift kein aspect-ratio
   am carousel-item Fallback -> per max-height begrenzen wie zuvor */
.home-hero.d-md-none .carousel-item {
    aspect-ratio: 4 / 3;
}

/* Fallback fuer Browser ohne aspect-ratio-Support: feste Hoehen */
@supports not (aspect-ratio: 1 / 1) {
    .home-hero .carousel-item {
        height: 280px;
    }

    .home-hero.d-md-none .carousel-item {
        height: auto;
    }

    .home-hero.d-md-none .home-hero__img {
        height: auto;
        max-height: 450px;
    }
}

/* Minimale, marken-neutrale Pfeile: nur duenner Chevron, kein Kreis,
   erscheinen sanft beim Hover ueber den Slider (nur Desktop). */
.home-hero__control {
    width: 8%;
    color: #fff;
    opacity: 0;
    transition: opacity .2s ease-in-out;
}

.home-hero:hover .home-hero__control {
    opacity: .9;
}

.home-hero__control:hover,
.home-hero__control:focus-visible {
    opacity: 1;
}

.home-hero__control span[aria-hidden] {
    text-shadow: 0 1px 4px rgba(0, 0, 0, .6);
}

.dropdown-menu li {
    position: relative;
}

.dropdown-menu .dropdown-submenu {
    display: none;
    position: absolute;
    left: 100%;
    top: -7px;
}

.dropdown-menu .dropdown-submenu-left {
    right: 100%;
    left: auto;
}

.dropdown-menu > li:hover > .dropdown-submenu {
    display: block;
}


/* Hintergr�nde Transparent
*/

.bg-primary-opacity {
    background-color: rgba(0, 123, 155, 0.1) !important;
}

.bg-primary-opacity-0025 {
    background-color: rgba(0, 123, 155, 0.025) !important;
}

.bg-secondary-opacity {
    background-color: rgba(108, 117, 125, 0.1) !important;
}

.bg-info-opacity {
    background-color: rgba(23, 162, 184, 0.1) !important;
}

.bg-warning-opacity {
    background-color: rgba(255, 193, 7, 0.1) !important;
}

.bg-warning-special {
    background-color: rgba(255, 204, 102) !important;
}

.bg-danger-opacity {
    background-color: rgba(220, 53, 69, 0.1) !important;
}

.suggesthover:hover {
    background-color: #f8f9fa;
}

/*!

CONTAINER ANPASSUNGEN

 */

.container {
    width: 100%;
    padding-right: 15px;
    padding-left: 15px;
    margin-right: auto;
    margin-left: auto
}

@media (min-width:576px) {
    .container {
        max-width: 540px
    }
}

@media (min-width:768px) {
    .container {
        max-width: 720px
    }
}

@media (min-width:992px) {
    .container {
        max-width: 960px
    }
}

@media (min-width:1200px) {
    .container {
        max-width: 1140px
    }
}

@media (min-width:1400px) {
    .container {
        max-width: 1340px
    }
}

@media (min-width:1600px) {
    .container {
        max-width: 1540px
    }
}

@media (min-width:1800px) {
    .container {
        max-width: 1740px
    }
}

.container-fluid, .container-lg, .container-md, .container-sm, .container-xl {
    width: 100%;
    padding-right: 15px;
    padding-left: 15px;
    margin-right: auto;
    margin-left: auto
}

@media (min-width:576px) {
    .container, .container-sm {
        max-width: 540px
    }
}

@media (min-width:768px) {
    .container, .container-md, .container-sm {
        max-width: 720px
    }
}

@media (min-width:992px) {
    .container, .container-lg, .container-md, .container-sm {
        max-width: 960px
    }
}

@media (min-width:1200px) {
    .container, .container-lg, .container-md, .container-sm, .container-xl {
        max-width: 1140px
    }
}

@media (min-width:1400px) {
    .container, .container-lg, .container-md, .container-sm, .container-xl {
        max-width: 1340px
    }
}

@media (min-width:1600px) {
    .container, .container-lg, .container-md, .container-sm, .container-xl {
        max-width: 1540px
    }
}

@media (min-width:1800px) {
    .container, .container-lg, .container-md, .container-sm, .container-xl {
        max-width: 1740px
    }
}

/* ==== Eingeloggter Header (theme-agnostisch) ================================== */
/* Farben kommen ueber BS-Utilities / Theme-CSS (vomberg-custom-hover*), hier nur
   Struktur, Radien, neutrale Grautoene und der Sticky-Shrink-Zustand.            */

/* Sticky-Wrapper um beide Header-Reihen; nur wenn kein separater Sticky-Banner
   (Praemien) aktiv ist -> Modifier wird im Markup gesetzt. */
.site-header {
    background-color: #fff;
    /* Luft zum Content: ohne Abstand klebt der Seiteninhalt direkt unter dem
       (sticky) Header. Opt-out fuer randlose Elemente: .site-header--flush. */
    margin-bottom: 1rem;
}

@media (min-width: 768px) {
    .site-header {
        margin-bottom: 1.5rem;
    }
}

/* Fuer Seiten, deren erstes Element randlos am Header anschliessen soll
   (z. B. vollflaechige Banner/Hero-Flaechen). */
.site-header--flush {
    margin-bottom: 0;
}

.site-header--sticky {
    position: sticky;
    top: 0;
    z-index: 1030;
    box-shadow: 0 2px 4px -2px rgba(0, 0, 0, .2);
    transition: box-shadow .3s ease;
}

.site-header--sticky.scrolled {
    box-shadow: 0 4px 16px rgba(0, 0, 0, .12);
}

.site-header__row1 {
    transition: padding .3s ease;
}

.site-header--sticky.scrolled .site-header__row1 {
    padding-top: .35rem !important;
    padding-bottom: .35rem !important;
}

.header-brand__logo {
    max-height: 34px;
    width: auto;
    max-width: 160px;
    transition: max-height .3s ease;
}

.site-header--sticky.scrolled .header-brand__logo {
    max-height: 30px;
}

/* Zentrales Suchfeld: volle Breite auf Mobil, FUELLT ab lg den freien Raum. */
.header-search {
    position: relative;
    width: 100%;
}

@media (min-width: 992px) {
    .header-search {
        width: auto;
        flex: 1 1 auto;
        min-width: 0; /* darf im Flex schrumpfen, statt zu ueberlaufen */
    }
}

/* Look des Suchfelds ueber Descendant-Selektoren, damit MiniSearch/MiniSearchSchneider
   (geteilte Partials, fichtner-Routing) unveraendert bleiben. */
.header-search .input-group {
    height: 40px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .04);
    border-radius: 8px;
}

.header-search .form-control {
    height: 40px;
    border: 1px solid #dde1e6;
    border-right: 0;
    border-top-left-radius: 8px;
    border-bottom-left-radius: 8px;
    padding-left: 2.4rem;
    font-size: .92rem;
    /* Lupe im Feld (neutral grau, theme-agnostisch) */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' stroke='%23adb5bd' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='7' cy='7' r='5'/%3E%3Cline x1='11' y1='11' x2='15' y2='15'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: .85rem center;
    background-size: .95rem .95rem;
}

.header-search .input-group-append .btn {
    height: 40px;
    padding: 0 1rem;
    border-top-right-radius: 8px;
    border-bottom-right-radius: 8px;
    font-size: .95rem;
}

/* Rechtes Aktions-Cluster (Utility-Toggles, Warenkorb, Konto) */
.header-actions {
    gap: .25rem;
}

/* Aktions-Items als Flex-Container: <a> und <button> werden identisch geometrisch
   zentriert (keine Baseline-/line-box-Effekte -> kein vertikaler Versatz). */
.header-actions .nav-item {
    display: flex;
    align-items: center;
}

/* Duenner vertikaler Trenner zwischen Toggles und Warenkorb/Konto */
.header-actions__divider {
    width: 1px;
    height: 22px;
    margin: 0 .35rem;
    background-color: #e6e9ec;
}

/* Kompakter Icon-Button fuer Utility-Toggles (Preise/Praesentation) */
.header-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    padding: 0;
    border: 0;
    border-radius: 8px;
    background-color: transparent;
    color: inherit;
    line-height: 1;
    cursor: pointer;
    transition: background-color .15s ease-in-out;
}

/* Icon exakt mittig (Baseline-/line-height-Quirks von <a> vs <button> neutralisieren) */
.header-action > i {
    display: block;
    line-height: 1;
}

.header-action:hover,
.header-action:focus {
    background-color: #f1f3f5;
    text-decoration: none;
}

.header-action:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 2px;
}

/* Einheitliche, gleichwertige Ghost-Buttons fuer Warenkorb & Konto (und Toggles).
   Transparent, Marken-Icon (via text-primary im Markup), Label klein, dezenter Hover. */
.header-action-btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    height: 36px;
    padding: 0 .6rem;
    border: 0;
    border-radius: 8px;
    background-color: transparent;
    color: #495057;
    font-size: .82rem;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease;
}

.header-action-btn:hover,
.header-action-btn:focus {
    background-color: #f1f3f5;
    color: #212529;
    text-decoration: none;
}

.header-action-btn:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 2px;
}

/* Geoeffneter Zustand (Dropdown offen) haelt den Hover-Hintergrund */
.header-action-btn[aria-expanded="true"] {
    background-color: #f1f3f5;
    color: #212529;
}

.header-action-btn__icon {
    font-size: 1.1rem;
    line-height: 1;
}

/* Icon-Wrapper: Anker fuer das Superscript-Badge; margin-right reserviert Platz
   fuer den Badge-Ueberhang, damit das Label frei steht (gleiche Optik wie Konto) */
.header-action-btn__iconwrap {
    position: relative;
    display: inline-flex;
    margin-right: 9px;
}

/* Zaehl-Badge als Superscript oben rechts, nur leicht am Icon anliegend */
.header-action-btn__badge {
    position: absolute;
    top: -8px;
    right: -11px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: 50rem;
    font-size: .58rem;
    font-weight: 700;
    line-height: 1;
    box-shadow: 0 0 0 2px #fff;
}

/* ---- Reihe 2: Kategorie-Ribbon (kompakt) ----------------------------------- */
.catbar {
    background-color: #fff;
    border-top: 1px solid #eef0f2;
    border-bottom: 1px solid #e9ecef;
    padding-top: .15rem;
    padding-bottom: .15rem;
}

.catbar .navbar-nav {
    align-items: center;
}

/* Sortiment-Button links: hervorgehoben per Soft Marken-Tint (aus currentColor,
   daher theme-agnostisch: Vomberg/Schneider/WEKU/fichtner ohne feste Farbwerte). */
.catbar__sortiment {
    position: relative;
    isolation: isolate;
    height: 32px;
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    border-radius: 8px;
    font-size: .9rem;
    font-weight: 600;
    padding: 0 .85rem;
}

.catbar__sortiment::before {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: -1;
    border-radius: inherit;
    background-color: currentColor; /* = Marken-Textfarbe (text-primary) */
    opacity: .09;
    transition: opacity .15s ease;
}

/* Statische Links (Ansprechpartner/Katalogportal/...) — echtes Styling statt der
   toten novum-custom-hover-Klasse; Farbe bleibt Marke (text-primary im Markup). */
.catbar .nav-link:not(.btn) {
    position: relative;
    font-size: .87rem;
    font-weight: 500;
    padding: .4rem .35rem;
}

.catbar .nav-link:not(.btn)::after {
    content: "";
    position: absolute;
    left: .35rem;
    right: .35rem;
    bottom: .3rem;
    height: 2px;
    background-color: currentColor;
    border-radius: 2px;
    transform: scaleX(0);
    transform-origin: left;
    opacity: .7;
    transition: transform .18s ease;
}

.catbar .nav-link:not(.btn):hover::after,
.catbar .nav-link:not(.btn):focus::after {
    transform: scaleX(1);
}

/* Kundenkontext (Admin/MobileSelling) rechts in der Ribbon */
.catbar__customer {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    font-size: .85rem;
    color: #495057;
    white-space: nowrap;
}

.catbar__customer:hover,
.catbar__customer:focus {
    color: #212529;
    text-decoration: none;
}

/* ---- Mobiles Off-Canvas (NavigatorLeft) ------------------------------------ */
/* Segmented-Control-Tabs (Sortiment / Konto) */
.offcanvas-seg {
    display: flex;
    gap: .25rem;
    padding: .25rem;
    background-color: #f1f3f5;
    border-radius: 50rem;
}

.offcanvas-seg__btn {
    flex: 1 1 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .4rem;
    padding: .45rem .75rem;
    border: 0;
    border-radius: 50rem;
    background-color: transparent;
    color: #495057;
    font-size: .95rem;
    font-weight: 600;
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease, box-shadow .15s ease;
}

.offcanvas-seg__btn.active {
    background-color: #fff;
    color: #212529;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .12);
}

/* Listen-Item: Icon + Label + Chevron, dezenter Grau-Hover (kein Blau-Vollflaechen) */
.offcanvas-nav__item {
    display: flex;
    align-items: center;
    gap: .8rem;
    width: 100%;
    padding: .7rem .55rem;
    border: 0;
    border-bottom: 1px solid #f1f3f5;
    border-radius: 8px;
    background-color: transparent;
    color: #212529;
    font-size: 1rem;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
    transition: background-color .15s ease;
}

.offcanvas-nav__item:hover,
.offcanvas-nav__item:focus {
    background-color: #f1f3f5;
    color: #212529;
    text-decoration: none;
}

.offcanvas-nav__icon {
    flex: 0 0 auto;
    width: 1.4rem;
    text-align: center;
}

.offcanvas-nav__label {
    flex: 1 1 auto;
}

.offcanvas-nav__chevron {
    flex: 0 0 auto;
    color: #adb5bd;
    font-size: 1.2rem;
}

/* ---- Sortiment-Button Hover: Tint kraeftiger ------------------------------- */
.catbar__sortiment:hover::before,
.catbar__sortiment:focus::before {
    opacity: .17;
}

.catbar__sortiment:hover,
.catbar__sortiment:focus {
    text-decoration: none;
}

/* ---- Sortiment-Dropdown: helles, aufgeraeumtes Fly-out-Menue ---------------- */
.sortiment-menu {
    padding: .4rem;
    border: 1px solid #e9ecef;
    border-radius: 12px;
    box-shadow: 0 14px 32px rgba(0, 0, 0, .10), 0 4px 10px rgba(0, 0, 0, .05);
}

/* Zeilen-Link (Haupt- und Unterebene gleich), Marken-Text via text-primary im Markup */
.sortiment-menu__link {
    display: flex;
    align-items: center;
    gap: .6rem;
    min-width: 260px;
    padding: .5rem .7rem;
    border-radius: 8px;
    font-size: .95rem;
    white-space: nowrap;
    text-decoration: none;
    transition: background-color .15s ease;
}

.sortiment-menu__link:hover,
.sortiment-menu__link:focus {
    background-color: #f1f3f5;
    text-decoration: none;
}

.sortiment-menu__label {
    flex: 1 1 auto;
}

.sortiment-menu__chevron {
    flex: 0 0 auto;
    color: #adb5bd;
    font-size: 1.1rem;
}

/* Fly-out-Submenue hell (ueberschreibt das bg-light aus dem Markup) */
.sortiment-menu .dropdown-submenu {
    padding: .4rem;
    background-color: #fff !important;
    border: 1px solid #e9ecef;
    border-radius: 12px;
    box-shadow: 0 14px 32px rgba(0, 0, 0, .10), 0 4px 10px rgba(0, 0, 0, .05);
}

/* ---- Tastatur-Fokus in allen Menuelisten (distinkt, nicht nur Hover-BG) ----- */
.sortiment-menu__link:focus-visible,
.account-menu__item:focus-visible,
.offcanvas-nav__item:focus-visible,
.offcanvas-seg__btn:focus-visible,
.catbar .nav-link:focus-visible,
.catbar__sortiment:focus-visible {
    outline: 2px solid #495057;
    outline-offset: -2px;
    background-color: #f1f3f5;
}

/* ---- Mobile: groessere Tap-Targets (>=44px empfohlen) ----------------------- */
@media (max-width: 991.98px) {
    .header-action {
        width: 44px;
        height: 44px;
    }

    .header-action-btn {
        height: 44px;
    }
}

/* ---- Such-Autosuggest: dichter am Feld + Hoehen-Fallback --------------------
   Scoped auf den Header (MiniSearch/MiniSearchSchneider bleiben unangetastet).
   Theme-CSS-Regeln (Vomberg .suggest-*) duerfen weiterhin ueberschreiben.     */
.header-search #suggestContainer {
    margin-top: .25rem !important; /* statt mt-3: Dropdown haengt direkt am Feld */
    max-height: 70vh;              /* Fallback fuer Themes ohne eigene Regel */
    overflow-y: auto;
}

/* ---- Message-Toast (Systemmeldungen, fixed oben rechts) --------------------- */
.message-toast {
    background-color: #fff;
    border: 1px solid #e9ecef;
    border-radius: 12px;
    box-shadow: 0 14px 32px rgba(0, 0, 0, .12), 0 4px 10px rgba(0, 0, 0, .06);
    padding: .9rem 2.5rem .9rem 1rem; /* rechts Platz fuer den Schliessen-Button */
}

.message-toast__icon {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    margin-right: .75rem;
    border-radius: 8px;
    background-color: #f1f3f5;
    font-size: 1rem;
}

.message-toast__body {
    flex: 1 1 auto;
    min-width: 0;
    font-size: .92rem;
    color: #212529;
}

.message-toast__body p {
    font-weight: 600;
}

/* Helles Konto-Dropdown (ersetzt den schweren bg-primary-Block) */
.account-menu {
    min-width: 264px;
    padding: .5rem;
    border: 1px solid #e9ecef;
    border-radius: 14px;
    box-shadow: 0 14px 32px rgba(0, 0, 0, .10), 0 4px 10px rgba(0, 0, 0, .05);
}

.account-menu__head {
    padding: .35rem .6rem .6rem;
    margin-bottom: .25rem;
    border-bottom: 1px solid #edf0f2;
}

.account-menu__eyebrow {
    text-transform: uppercase;
    letter-spacing: .08em;
    font-size: .72rem;
    font-weight: 700;
}

.account-menu__item {
    display: flex;
    align-items: center;
    gap: .7rem;
    padding: .5rem .6rem;
    width: 100%;
    border: 0;
    border-radius: 8px;
    background-color: transparent;
    color: #212529;
    font-size: .97rem;
    text-align: left;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color .15s ease-in-out;
}

.account-menu__item:hover,
.account-menu__item:focus {
    background-color: #f1f3f5;
    color: #212529;
    text-decoration: none;
}

.account-menu__item-icon {
    flex: 0 0 auto;
    width: 1.25rem;
    text-align: center;
}

.account-menu__foot {
    margin-top: .25rem;
    padding-top: .25rem;
    border-top: 1px solid #edf0f2;
}

/* ==== Breadcrumbs (global) + Gruppen-Kategorie-Hero + Bild-Banner ==================
   Konsistent zum Header-/Startseiten-Relaunch. Farben kommen ueber BS-Utilities
   (text-primary/bg-primary im Markup) -> theme-aware; hier nur Struktur, Radien und
   neutrale Grautoene. Marken-Tints via currentColor, keine festen Farbwerte. */

/* ---- Breadcrumb-Ribbon GLOBAL: ueberschreibt Bootstrap .breadcrumb -----------------
   Loest den grauen Default-Kasten + den "/"-Trenner ab. Markup bleibt Bootstrap
   (ol.breadcrumb > li.breadcrumb-item); Marke kommt aus text-primary am <a>. */
.breadcrumb {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    background-color: transparent;
    padding: .25rem 0;
    margin-bottom: 1rem;
    border-radius: 0;
    font-size: .85rem;
    line-height: 1.4;
}

/* inline-flex zentriert Chevron (::before) + Link vertikal sauber (Desktop & Mobile) */
.breadcrumb-item {
    display: inline-flex;
    align-items: center;
    min-width: 0;
}

/* Chevron-Trenner statt BS-"/" — neutral, ohne FA-Abhaengigkeit */
.breadcrumb-item + .breadcrumb-item {
    padding-left: 0;
}

.breadcrumb-item + .breadcrumb-item::before {
    content: "\203A";
    color: #adb5bd;
    padding: 0 .45rem;
    font-size: 1rem;
    line-height: 1;
}

/* Link erbt Marke aus text-primary im Markup; animierte currentColor-Unterstreichung
   analog .catbar .nav-link::after */
.breadcrumb-item:not(.active) a {
    position: relative;
    font-weight: 500;
    text-decoration: none;
}

.breadcrumb-item:not(.active) a::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -2px;
    height: 2px;
    background-color: currentColor;
    border-radius: 2px;
    transform: scaleX(0);
    transform-origin: left;
    opacity: .7;
    transition: transform .18s ease;
}

.breadcrumb-item:not(.active) a:hover,
.breadcrumb-item:not(.active) a:focus {
    text-decoration: none;
}

.breadcrumb-item:not(.active) a:hover::after,
.breadcrumb-item:not(.active) a:focus::after {
    transform: scaleX(1);
}

/* Aktueller (aktiver) Eintrag: neutral, kein Link-Look */
.breadcrumb-item.active,
.breadcrumb-item.active a {
    color: #495057;
    font-weight: 600;
    text-decoration: none;
}

/* ---- Kategorie-Hero (loest den schlichten h4 + border-bottom Titelkopf ab) ------- */
.category-hero {
    background-color: #f6f8fb;
    border: 1px solid #edf0f2;
    border-radius: 14px;
    padding: 1.1rem 1.25rem;
    /* Das Panel wird im Markup als d-flex flex-wrap genutzt (Titelblock links,
       Aktionen rechts). Bricht die Aktionsgruppe auf schmalen Viewports um, klebte sie
       bisher direkt unter dem Titel - flex-wrap erzeugt von sich aus keinen Zeilenabstand.
       gap wirkt nur auf Flex-Container, ist also fuer andere Verwendungen wirkungslos. */
    row-gap: .85rem;
    column-gap: 1rem;
}

/* ---- Gruppen-Bild-Banner (Carousel): moderne Rundung/Schatten/Rahmen ------------ */
.group-banner {
    border: 1px solid #e9ecef;
    border-radius: 14px;
    overflow: hidden;
    box-shadow: 0 14px 32px rgba(0, 0, 0, .10), 0 4px 10px rgba(0, 0, 0, .05);
}

.group-banner .carousel-inner {
    background-color: #fff;
}

/* Groesse wie Startseiten-Hero: vollbreit + einheitliche kompakte Hoehe via
   aspect-ratio + object-fit:cover. Mobile (d-md-none) niedriger. Bild fuellt die
   Flaeche und wird ggf. beschnitten (bewusst, wie .home-hero). max-height deckelt
   die Hoehe fuer Ultrawide (Desktop) bzw. nahe dem 768px-Breakpoint (Mobile). */
.group-banner .carousel-item {
    aspect-ratio: 24 / 5;
    max-height: 380px;
}

.group-banner.d-md-none .carousel-item {
    aspect-ratio: 1 / 1;
    max-height: 440px;
}

.group-banner .carousel-item > a {
    display: block;
    width: 100%;
    height: 100%;
}

.group-banner .carousel-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Fallback fuer Browser ohne aspect-ratio (analog .home-hero) */
@supports not (aspect-ratio: 1 / 1) {
    .group-banner .carousel-item {
        height: 300px;
    }

    .group-banner.d-md-none .carousel-item {
        height: 380px;
    }
}

/* Indikatoren dezenter: neutrale Pillen, aktiver Punkt in Markenfarbe (text-primary
   im Markup -> currentColor) */
.group-banner .carousel-indicators li {
    width: 8px;
    height: 8px;
    border-radius: 50rem;
    border: 0;
    background-color: #ced4da;
    opacity: 1;
    transition: background-color .15s ease, width .15s ease;
}

.group-banner .carousel-indicators li.active {
    width: 22px;
    background-color: currentColor;
}

/* ==== Produkt-Hero (voll breit ueber beiden Spalten; Pendant zu .category-hero) ===
   Theme-agnostisch: hier nur Struktur/Radien/neutrale Grautoene, Marke kommt
   ausschliesslich ueber BS-Utilities im Markup (text-primary/bg-primary). */
.product-hero {
    background-color: #f6f8fb;
    border: 1px solid #edf0f2;
    border-radius: 14px;
    padding: 1.1rem 1.25rem;
}

/* Feste Hoehe reserviert das Layout VOR dem Bild-Load. Ohne sie springt die Seite
   beim Logo-Load nach und das Scroll-Restore in _Layout.cshtml landet daneben. */
.product-hero__logo {
    height: 56px;
    width: auto;
    max-width: 160px;
    object-fit: contain;
}

@media (max-width: 575.98px) {
    .product-hero__logo {
        height: 40px;
    }
}

/* Piktogramme (unter der Galerie): gleiche Hoehen-Reservierung, kleinere Skala. */
.product-hero__pictos {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
}

.product-hero__picto {
    height: 40px;
    width: auto;
    object-fit: contain;
}

/* Aktions-Buttons oben rechts im Hero. */
.product-hero__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: .5rem;
}

/* Titel: lange Artikelnamen duerfen auf schmalen Viewports nicht vier Zeilen fressen. */
.product-hero__title {
    overflow-wrap: break-word;
    min-width: 0;
}

@media (max-width: 575.98px) {
    .product-hero__title {
        font-size: 1.15rem;
    }
}

/* Akzentlinie und Artikelnr.-Chip teilen sich eine Zeile statt zu stapeln. */
.product-hero__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .75rem;
}

/* Sprungmarken: auf schmalen Viewports einzeilig seitlich scrollbar statt Umbruch
   auf zwei Zeilen. Scrollbar ausgeblendet, Pills behalten ihre volle Groesse. */
.product-hero__jump {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
}

@media (max-width: 575.98px) {
    .product-hero__jump {
        flex-wrap: nowrap;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        /* Negativer Rand + Padding: die naechste Pill wird angeschnitten sichtbar,
           was die Scrollbarkeit signalisiert, ohne dass sie am Rand klebt. */
        margin-right: -1.25rem;
        padding-right: 1.25rem;
    }

    .product-hero__jump::-webkit-scrollbar {
        display: none;
    }

    .product-hero__jump > .btn {
        flex: 0 0 auto;
        white-space: nowrap;
    }
}

/* Sprungmarken-Ziele unter dem sticky .site-header freihalten - sonst landet der
   angesprungene Block hinter dem Header. */
#article_table,
#Beschreibung,
#assignedProducts,
#portalPartnerGroup,
#fastEntry {
    scroll-margin-top: 6rem;
}

/* ==== Produktgalerie (Carousel) ==================================================
   BEWUSST NICHT .group-banner wiederverwenden: dort erzwingen aspect-ratio 24/5 +
   object-fit:cover einen Panorama-Beschnitt. Produktbilder muessen vollstaendig
   sichtbar bleiben -> contain. */
.product-gallery {
    border: 1px solid #e9ecef;
    border-radius: 14px;
    overflow: hidden;
    background-color: #fff;
    box-shadow: 0 14px 32px rgba(0, 0, 0, .10), 0 4px 10px rgba(0, 0, 0, .05);
}

/* Quadratisch, weil die Quellbilder quadratisch vorgerendert werden (100/500/800 px,
   siehe docs/Admin-Anleitung-Bildoptimierung.md). Ein 4:3-Rahmen wuerde das Bild bei
   object-fit:contain auf 75 % der Breite schrumpfen und links/rechts Leerstreifen
   lassen. Ersetzt zugleich das Inline-min-height:400px und die Inline-max-height:450px
   und reserviert die Hoehe vor dem Bild-Load (siehe Scroll-Restore oben). */
.product-gallery .carousel-item {
    aspect-ratio: 1 / 1;
    max-height: 520px;
}

.product-gallery .carousel-item > a {
    display: block;
    width: 100%;
    height: 100%;
}

.product-gallery .carousel-item img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

@supports not (aspect-ratio: 1 / 1) {
    .product-gallery .carousel-item {
        height: 460px;
    }
}

.product-gallery .carousel-indicators li {
    width: 8px;
    height: 8px;
    border-radius: 50rem;
    border: 0;
    background-color: #ced4da;
    opacity: 1;
    transition: background-color .15s ease, width .15s ease;
}

.product-gallery .carousel-indicators li.active {
    width: 22px;
    background-color: currentColor;
}

/* Pfeile im Geist der Startseite (.home-hero__control): duenner Chevron, kein Kasten,
   erscheinen sanft beim Hover. Unterschied: die Startseite liegt auf dunklen Fotos und
   nutzt Weiss - die Produktgalerie steht auf Weiss, daher neutrales Dunkelgrau. */
.product-gallery__control {
    width: 10%;
    color: #495057;
    opacity: 0;
    transition: opacity .2s ease-in-out, color .15s ease;
}

.product-gallery:hover .product-gallery__control {
    opacity: .9;
}

.product-gallery__control:hover,
.product-gallery__control:focus-visible {
    color: #212529;
    opacity: 1;
}

.product-gallery__control span[aria-hidden] {
    text-shadow: 0 1px 4px rgba(255, 255, 255, .8);
}

/* Touch-Geraete kennen kein Hover -> Pfeile dauerhaft sichtbar lassen. */
@media (hover: none) {
    .product-gallery__control {
        opacity: .9;
    }
}

/* ==== Gemeinsame Merkmale (Produktseite, rechte Spalte) ==========================
   Panel im Relaunch-Stil statt Bootstrap-Card. Auf Mobile einklappbar, ab md immer
   offen - deshalb wird der Toggle dort per pointer-events stillgelegt. */
.common-features {
    background-color: #fff;
    border: 1px solid #edf0f2;
    border-radius: 14px;
    padding: 1.1rem 1.25rem;
}

.common-features__toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    cursor: pointer;
}

.common-features__chevron {
    color: #adb5bd;
    transition: transform .2s ease;
}

.common-features__toggle[aria-expanded="true"] .common-features__chevron {
    transform: rotate(180deg);
}

.common-features__item {
    display: flex;
    flex-wrap: wrap;
    padding: .5rem 0;
    font-size: .9rem;
    border-bottom: 1px solid #f1f3f5;
}

.common-features__label {
    flex: 0 0 50%;
    max-width: 50%;
    padding-right: .75rem;
    font-weight: 600;
    color: #495057;
}

.common-features__value {
    flex: 1 1 auto;
    min-width: 0;
    color: #212529;
    overflow-wrap: break-word;
}

/* Sehr schmale Viewports: Label ueber Wert statt nebeneinander. */
@media (max-width: 400px) {
    .common-features__label,
    .common-features__value {
        flex: 1 1 100%;
        max-width: 100%;
    }

    .common-features__label {
        padding-right: 0;
    }
}

/* Ab md immer offen; Einklappen ist bewusst nur ein Mobile-Verhalten (der Toggle
   selbst traegt dort d-md-none, die Ueberschrift wird statisch gerendert). */
@media (min-width: 768px) {
    .common-features__list.collapse {
        display: block !important;
    }
}

/* ==== Ansprechpartner-Karten (PortalPartner) im Relaunch-Stil =====================
   Runder Avatar + Kontakt-Pills. Theme-agnostisch: Marke via BS-Utilities im Markup
   (text-primary/btn-outline-primary), hier nur Struktur/Radien/neutrale Grautoene. */
.partner-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    height: 100%;
    background-color: #fff;
    border: 1px solid #edf0f2;
    border-radius: 14px;
    padding: 1.5rem 1.25rem;
    transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
}

.partner-card:hover {
    transform: translateY(-4px);
    border-color: transparent;
    box-shadow: 0 14px 32px rgba(0, 0, 0, .10), 0 4px 10px rgba(0, 0, 0, .05);
}

.partner-card__avatar {
    width: 120px;
    height: 120px;
    border-radius: 50%;
    object-fit: cover;
    background-color: #f8f9fa;
    border: 3px solid #f1f3f5;
}

.partner-card__name {
    margin-top: .85rem;
    font-size: 1.05rem;
    font-weight: 700;
    line-height: 1.2;
}

.partner-card__area {
    margin-top: .2rem;
}

.partner-card__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: .4rem;
    margin-top: .9rem;
}

.partner-card__memo {
    margin-top: .85rem;
    font-size: .85rem;
    line-height: 1.4;
}

.partner-card__memo p {
    margin: 0;
}

/* Neutraler Pill-Chip (z.B. Artikelzaehler in .category-hero). Nicht interaktiv;
   theme-agnostisch (neutrale Grautoene). Fuer interaktive Login-Chips: .login-chip. */
.hero-chip {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    font-size: .82rem;
    font-weight: 600;
    line-height: 1;
    padding: .35rem .75rem;
    border-radius: 50rem;
    color: #495057;
    background-color: #f1f3f5;
    white-space: nowrap;
}

/* ==== Produkt-/Gruppen-Kacheln (Relaunch) ==================================
   Wiederverwendbarer Kachel-Baustein fuer Gruppen-/Kategorieseite (Produkte,
   Untergruppen, "koennte Sie auch interessieren"). Theme-agnostisch: neutrale
   BS-Defaults/Grautoene, KEINE Marken-Hardcodes (Marke via text-primary im
   Markup). Radius 14 + Signatur-Schatten + Hover-Lift wie die uebrigen
   Relaunch-Komponenten. Cherry-pick-tauglich nach fichtner. */

/* 5er-Raster-Helfer: BS4 kennt kein 5-Spalten-Grid (12/5 geht nicht auf). */
@media (min-width: 1200px) {
    .col-xl-5th {
        flex: 0 0 20%;
        max-width: 20%;
    }
}

.tile-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    background: #fff;
    border: 1px solid #e9ecef;
    border-radius: 14px;
    /* WICHTIG: overflow MUSS sichtbar bleiben, sonst klippt die Karte die Dropdowns
       aus ArticleGroup/StockLevel (Bestand, Wunschliste, Mengen-Vorschlag). Der Titel
       sitzt oben (kein Vollflaechen-BG an den Ecken); die Karten-Rundung uebernimmt der
       border-radius (Hintergrund wird ohnehin am Radius geclippt). Bild-Ecken bei
       Gruppen-Kacheln werden separat gerundet (.tile-card--group .tile-card__media). */
    overflow: visible;
    transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
}

    /* Hover-Feedback bewusst NUR ueber den Schatten (kein transform: translateY):
       ein transform wuerde einen Stacking-Context + Containing-Block fuer position:fixed
       erzeugen und damit die Karten-Dropdowns (Bestand/Wunschliste) hinter die naechste
       Reihe legen UND die VPE-Preise-Modals (PriceGroup) im 1:1-Fall verzerren/klippen.
       Ohne transform liegen die (positionierten) Dropdowns ohnehin ueber den statischen
       Nachbarkacheln, und Modals positionieren korrekt zum Viewport. */
    .tile-card:hover {
        box-shadow: 0 14px 32px rgba(0,0,0,.10), 0 4px 10px rgba(0,0,0,.05);
        border-color: #dee2e6;
    }

/* Bildbereich: festes Seitenverhaeltnis, Produktbild eingepasst (contain,
   kein Beschnitt). position:relative -> Anker fuer Lieferantenlogo/Flag-Badges. */
.tile-card__media {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 4 / 3;
    padding: .75rem;
    background: #fff;
}

    /* ueberschreibt das von ResourceList gesetzte .card-img-top (Spezifitaet 0,1,1 > 0,1,0). */
    .tile-card__media img {
        max-width: 100%;
        max-height: 100%;
        width: auto;
        height: auto;
        object-fit: contain;
    }

/* Fallback fuer Browser ohne aspect-ratio-Support. */
@supports not (aspect-ratio: 4 / 3) {
    .tile-card__media {
        height: 190px;
    }
}

/* Titel: max. 2 Zeilen + Ellipsis, feste Mindesthoehe -> gleich hohe Kacheln. */
.tile-card__title {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: .9rem;
    font-weight: 600;
    line-height: 1.3;
    min-height: 2.6em;
}

/* Preis/Warenkorb unten fixieren (gleiche Grundlinie ueber alle Kacheln). */
.tile-card__footer {
    margin-top: auto;
}

/* Gruppen-/Kategorie-Kachel: Titel mittig, darf 3 Zeilen nutzen. */
.tile-card--group .tile-card__title {
    -webkit-line-clamp: 3;
    text-align: center;
}

/* Gruppen-Kachel: Bild liegt UNTEN -> untere Ecken runden (Karte hat kein
   overflow:hidden mehr, sonst wuerde der weisse Bild-BG die Rundung ueberdecken). */
.tile-card--group .tile-card__media {
    border-bottom-left-radius: 14px;
    border-bottom-right-radius: 14px;
}

/* 1:1-Produkt (ArticleGroup): Bestand + Wunschliste + Menge/Warenkorb muessen in die
   schmalere 5er-Kachel passen -> bei Platzmangel umbrechen statt ueberlaufen.
   Nur in der Kachel (Listen-Ansicht/Produktseite unberuehrt). */
.tile-card__footer .d-flex.flex-row.align-items-center {
    flex-wrap: wrap;
    row-gap: .5rem;
}

/* Marken-Dropdowns (Bestand/Wunschliste/Mengen-Vorschlag) im Relaunch-Stil: weiche
   Rundung + Signatur-Schatten, konsistent in Kachel UND Listen-Ansicht. Marken-BG
   (bg-primary) kommt aus dem Markup. */
.dropdown-menu.bg-primary {
    border: 0;
    border-radius: 12px;
    box-shadow: 0 14px 32px rgba(0,0,0,.10), 0 4px 10px rgba(0,0,0,.05);
    overflow: hidden;
}

/* Wunschlisten-Menue (ArticleGroup): braucht Breite fuer Listenname + Button, darf auf
   kleinen Viewports aber nicht ueber den Bildschirm hinauslaufen (fruher inline 350px). */
.wishlist-menu {
    min-width: min(350px, calc(100vw - 2rem));
}

/* Marken-Dropdowns (bg-primary: Bestand, Wunschliste, Mengen-Vorschlag): der GLOBALE
   gruene .dropdown-item:hover aus dem Theme-CSS (#009a3e) wirkt auf blauem Grund
   unschoen (Gruen-auf-Blau). Stattdessen dezentes, theme-agnostisches Weiss-Overlay,
   das auf JEDER Markenfarbe funktioniert. Hoehere Spezifitaet als die Theme-Regel
   (.dropdown-item:hover, 0,1,1) -> gewinnt ohne !important. Gilt ueberall, wo diese
   Marken-Menues erscheinen (Kachel + Listen-Ansicht). */
.dropdown-menu.bg-primary .dropdown-item:hover,
.dropdown-menu.bg-primary .dropdown-item:focus {
    background-color: rgba(255, 255, 255, .18);
    color: #fff;
}

/* Produkt-Listen-Ansicht (Gruppe/Suche, Umschalter "Liste"): Zellen vertikal zentriert
   fuer ruhige Zeilen; Row-Hover-Feedback via Bootstraps .table-hover, neutrale Trenner
   ueber .border-bottom an den <tr>. Nur direkte Zellen (nicht verschachtelte Modal-
   Tabellen). Theme-agnostisch. */
.product-list > tbody > tr > td {
    vertical-align: middle;
}

/* Bootstraps .table-responsive setzt overflow-x:auto; dadurch berechnet sich overflow-y
   ebenfalls zu auto -> die Dropdowns aus ArticleGroup/StockLevel (Bestand, Wunschliste)
   wuerden am Tabellenrand abgeschnitten. Ab md wird kein horizontaler Scroll gebraucht
   -> Overflow freigeben (Kachel-Ansicht ist bereits entsprechend gehaertet).
   Unter md bleibt der horizontale Scroll erhalten (dort ist die Liste die Nebenansicht). */
@media (min-width: 768px) {
    .product-list-wrap {
        overflow: visible;
    }
}

/* ==== Ansichtswechsel (Kachel|Liste) – segmentierter Toggle (_ViewSwitch) ==========
   Pill-Segmentkontrolle, neutrale Grautoene; aktives Segment bekommt bg-primary/text-white
   aus dem Markup (theme-aware). */
.view-switch {
    display: inline-flex;
    border: 1px solid #dee2e6;
    border-radius: 50rem;
    overflow: hidden;
    background: #fff;
}

.view-switch__btn {
    border: 0;
    background: transparent;
    color: #6c757d;
    padding: .4rem .8rem;
    line-height: 1;
    font-size: 1rem;
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease;
}

    .view-switch__btn:not(.active):hover {
        background-color: #f1f3f5;
        color: #495057;
    }

    .view-switch__btn:focus {
        outline: 2px solid currentColor;
        outline-offset: -2px;
    }

/* ==== SitePager – zentrale Pagination im Relaunch-Stil ============================
   Runde Einzel-Items (Radius 8), neutrale Raender/Hover; aktive Seite bekommt
   bg-primary/text-white aus dem Markup (theme-aware). Logik unveraendert. */
.pagination-relaunch {
    gap: .3rem;
}

    .pagination-relaunch .page-item {
        margin: 0;
    }

    .pagination-relaunch .page-link {
        margin: 0; /* Bootstraps -1px-Rand aufheben -> saubere, runde Einzel-Items mit gap */
        border: 1px solid #dee2e6;
        border-radius: 8px;
        color: #495057;
        min-width: 2.3rem;
        text-align: center;
        transition: background-color .15s ease, border-color .15s ease, color .15s ease;
    }

        .pagination-relaunch .page-link:hover {
            background-color: #f1f3f5;
            border-color: #dee2e6;
            color: #212529;
        }

    .pagination-relaunch .page-item.active .page-link {
        border-color: transparent;
    }

/* ==== Modal-Dialoge – einheitlicher Relaunch-Stil (app-weit) =====================
   Alle Modals nutzen dieselbe Struktur (.modal-content > .modal-header > h5.modal-title
   + button.close). Ein globaler, theme-agnostischer Stil vereinheitlicht sie:
   Preis-/VPE-Modals (PriceGroup/PriceTable), Merkmale/Artikelinfo (Tabellenansicht),
   Warenkorb/Account/MobileSales. Marke kommt weiter aus dem Markup (.modal-title
   .text-primary). BEWUSST kein overflow:hidden -> Dropdowns/Selects in Modals bleiben
   unbeschnitten; die weissen Ecken rundet der border-radius ohnehin. */
.modal-content {
    border: 0;
    border-radius: 14px;
    box-shadow: 0 24px 48px rgba(0,0,0,.18), 0 8px 16px rgba(0,0,0,.08);
}

.modal-header {
    align-items: center;
    padding: 1rem 1.25rem;
    border-bottom: 1px solid #edf0f2;
    border-top-left-radius: 14px;
    border-top-right-radius: 14px;
}

.modal-title {
    font-weight: 600;
}

.modal-body {
    padding: 1.25rem;
}

.modal-footer {
    border-top: 1px solid #edf0f2;
}

/* Close-Button: ruhiger, mit dezentem Hover-Feld statt nacktem "x". */
/* ---- Datenlastige Dialoge ---------------------------------------------------------
   Preis-/Staffelinfo, Artikelinformationen, Stuecklisten-Komponenten, Dateien: Dialoge,
   die im Kern eine kleine Tabelle zeigen. Die Basis-Modalregeln oben gelten weiter,
   hier wird nur die Innenseite ruhiger und kompakter - sonst stehen dort Zeilen in
   voller Fliesstextgroesse mit Bootstrap-Standardpadding, was schnell unuebersichtlich
   wird. Modifier am .modal-content, damit Dialoge ohne Tabelle unberuehrt bleiben. */
.modal-content--data .modal-title {
    font-size: 1rem;
}

.modal-content--data .modal-body {
    padding: 1rem 1.25rem;
    font-size: .875rem;
}

/* Betraege und Mengen fluchten - wie in .data-table__num */
.modal-content--data .modal-body {
    font-variant-numeric: tabular-nums;
}

.modal-content--data .modal-body > :last-child {
    margin-bottom: 0;
}

.modal-content--data .modal-body table {
    margin-bottom: 0;
}

.modal-content--data .modal-body td,
.modal-content--data .modal-body th {
    padding: .4rem .5rem;
    vertical-align: middle;
    border-color: #edf0f2;
}

.modal-content--data .modal-body thead th {
    background-color: #f8f9fa;
    color: #495057;
    font-weight: 600;
    font-size: .8125rem;
    border-bottom: 2px solid #e9ecef;
    white-space: nowrap;
}

/* Die Hervorhebungen im Preisdialog (grosser Betrag) eine Stufe zurueckdrehen -
   im kompakten Dialog wirkte h5 wie eine zweite Ueberschrift. */
.modal-content--data .modal-body h5 {
    font-size: 1.05rem;
    margin-bottom: 0;
}

/* Trennlinien zwischen den Bloecken statt harter .border-bottom-Kanten */
.modal-content--data .modal-body .border-bottom {
    border-bottom-color: #edf0f2 !important;
    padding-bottom: .5rem;
    margin-bottom: .5rem;
}

.modal-header .close {
    padding: .5rem;
    margin: -.5rem -.5rem -.5rem auto;
    border-radius: 8px;
    opacity: .55;
    transition: background-color .15s ease, opacity .15s ease;
}

    .modal-header .close:hover {
        opacity: 1;
        background-color: #f1f3f5;
    }

/* ==== Merkmal-Filter (ArticleFeatureFilter) – Facetten-Leiste + aktive Chips =======
   Theme-agnostisch: neutrale Grautoene; Marke nur via .text-primary im Markup
   (currentColor-Trick fuer aktives Merkmal/Wert). Facetten-Menues sind neutral WEISS
   (nicht mehr bg-primary), mit Count-Badge + Haekchen bei Auswahl. */
.filter-bar {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    align-items: center;
}

/* Facetten-Button (ein Merkmal): neutrales Outline-Pill */
.filter-facet {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .4rem .85rem;
    border: 1px solid #dee2e6;
    border-radius: 50rem;
    background: #fff;
    color: #495057;
    font-size: .875rem;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    text-decoration: none;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease, box-shadow .15s ease;
}

    .filter-facet:hover {
        background-color: #f1f3f5;
        color: #212529;
        text-decoration: none;
    }

    .filter-facet:focus {
        outline: 2px solid currentColor;
        outline-offset: 2px;
    }

    .filter-facet__chevron {
        font-size: .7rem;
        color: #adb5bd;
    }

/* aktives Merkmal: Marken-Toenung (Element traegt .text-primary -> currentColor = Marke) */
.filter-facet--active {
    border-color: currentColor;
    box-shadow: inset 0 0 0 1px currentColor;
}

/* Wertemenue: neutral weiss, weiche Rundung + Signatur-Schatten */
.filter-facet-menu {
    border: 0;
    border-radius: 12px;
    box-shadow: 0 14px 32px rgba(0,0,0,.10), 0 4px 10px rgba(0,0,0,.05);
    padding: .35rem;
    min-width: 230px;
    max-height: 60vh;
    overflow-y: auto;
}

    .filter-facet-menu .dropdown-item {
        display: flex;
        align-items: center;
        gap: .5rem;
        border-radius: 8px;
        padding: .45rem .6rem;
        color: #212529;
        font-size: .875rem;
        white-space: normal;
    }

        /* neutraler Hover -> ueberschreibt den globalen gruenen Theme-.dropdown-item:hover */
        .filter-facet-menu .dropdown-item:hover,
        .filter-facet-menu .dropdown-item:focus {
            background-color: #f1f3f5;
            color: #212529;
        }

.filter-value__check {
    visibility: hidden;
    font-size: .8rem;
    width: 1em;
}

.filter-value--active {
    font-weight: 700;
}

    .filter-value--active .filter-value__check {
        visibility: visible;
    }

.filter-count {
    margin-left: auto;
    color: #6c757d;
    font-size: .78rem;
    font-weight: 600;
    white-space: nowrap;
}

/* Aktive-Filter-Chips */
.filter-chip {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .28rem .35rem .28rem .7rem;
    border-radius: 50rem;
    background: #f1f3f5;
    color: #212529;
    font-size: .82rem;
}

    .filter-chip img.FeatureValueImage {
        max-height: 1.4rem;
        margin: 0;
    }

.filter-chip__remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.35rem;
    height: 1.35rem;
    border-radius: 50rem;
    background: #fff;
    color: #6c757d;
    text-decoration: none;
    transition: background-color .15s ease, color .15s ease;
}

    .filter-chip__remove:hover {
        background: #e2e6ea;
        color: #212529;
        text-decoration: none;
    }

.filter-reset {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    color: #6c757d;
    font-size: .82rem;
    font-weight: 600;
    text-decoration: none;
}

    .filter-reset:hover {
        color: #212529;
        text-decoration: underline;
    }

/* ==== Suche: Suggest-Treffer, Vorschlaege, Leer-/Fehlerzustand ====================
   Theme-agnostisch (neutrale BS-Defaults). Die Marken-Toenung der Suggest-Flaechen kommt
   weiterhin aus dem Theme-CSS; hier stehen nur die Ergaenzungen, die in beiden Themes
   gleich aussehen sollen. */

/* Artikelnummer unter dem Treffernamen. Das Suchfeld wirbt im Placeholder mit der
   Artikelnummer - dann muss sie im Treffer auch auftauchen. */
.suggest-product-meta {
    display: block;
    margin-top: 2px;
    font-size: .74rem;
    color: #5c636a; /* auf #f8f9fa ~6,4:1 */
    font-variant-numeric: tabular-nums;
}

/* Suchbegriff-Vorschlaege: stehen jetzt unter den Treffern und sind bewusst ruhig gehalten.
   Vorher waren sie als gefuellte Marken-Chips das lauteste Element der Flaeche. */
.suggest-terms {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}

.suggest-terms__label {
    font-size: .78rem;
    color: #6c757d;
}

.suggest-term {
    display: inline-flex;
    align-items: center;
    min-height: 32px;
    padding: 6px 12px;
    border-radius: 50rem;
    background: #f1f3f5;
    color: #212529;
    font-size: .8rem;
    text-decoration: none;
}

    .suggest-term:hover,
    .suggest-term:focus {
        background: #e2e6ea;
        color: #212529;
        text-decoration: none;
    }

/* Kategorie-Hover: Text bleibt dunkel. Das Theme faerbt ihn sonst gruen auf hellgruenem
   Grund (3,0:1) - unter dem AA-Grenzwert. Hoehere Spezifitaet als .vomberg-custom-hover:hover.
   Bewusst NUR :hover - bei :focus wuerde die dunkle Farbe ueber currentColor auch den
   Fokusring einfaerben und ihm die Markenfarbe nehmen. */
.suggest-category-item.vomberg-custom-hover:hover {
    color: #212529 !important;
}

/* Fokus: das Dropdown war die einzige interaktive Komponente im Header ohne Fokusring
   (bootstrap-reboot entfernt den Browser-Default). Gleiches Muster wie .header-action. */
.suggest-product-item:focus-visible,
.suggest-category-item:focus-visible,
.suggest-term:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: -2px;
}

/* Touch: Kategorien lagen bei 36px (mobil 28px), Vorschlaege bei 25px. */
@media (pointer: coarse) {
    .suggest-category-item {
        min-height: 44px;
    }

    .suggest-term {
        min-height: 44px;
        padding-left: 16px;
        padding-right: 16px;
    }

    .suggest-terms {
        gap: 10px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .suggest-product-item,
    .suggest-category-item,
    .suggest-category-item i,
    .suggest-term {
        transition: none !important;
    }

        .suggest-product-item:hover,
        .suggest-category-item:hover {
            transform: none !important;
        }

    .suggest-loading-spinner {
        animation: none !important;
    }
}

/* Artikelnummer in der Produktkachel (nur bei Einzelartikel-Produkten). Die Zeile wird auch
   leer gerendert und haelt ihre Hoehe, damit Kacheln mit und ohne Nummer buendig bleiben. */
.tile-card__artnr {
    font-size: .75rem;
    line-height: 1.2;
    min-height: 1.2em;
    color: #6c757d;
    font-variant-numeric: tabular-nums;
    margin-top: 2px;
}

/* Leer- und Fehlerzustand der Suchergebnisseite. */
.search-empty {
    padding: 56px 20px;
    max-width: 46rem;
    margin: 0 auto;
}

/* Lieferantenlogo/Flag-Icons als Overlay im Bildbereich. */
.tile-card__badge {
    position: absolute;
    top: .5rem;
    z-index: 1;
    display: flex;
    flex-direction: column;
    gap: .25rem;
}

.tile-card__badge--supplier {
    left: .5rem;
}

.tile-card__badge--flags {
    right: .5rem;
}

/* ==== Gruppen-/Kategorie-Beschreibung (ERP-HTML) im Relaunch-Stil =================
   Admin-editierbares HTML aus dem ERP (Bilder, Ueberschriften, Listen, Tabellen).
   Container theme-agnostisch: neutrale BS-Defaults/Grautoene, KEINE Marken-Hardcodes
   (Links bleiben BS-Default -> mandantenunabhaengig, cherry-pick-tauglich). Bilder
   werden responsiv gemacht und mit sanften Radien versehen. */
.group-description {
    background-color: #fff;
    border: 1px solid #edf0f2;
    border-radius: 14px;
    padding: 1.75rem;
    line-height: 1.65;
    overflow-wrap: break-word;
}

@media (max-width: 575.98px) {
    .group-description {
        padding: 1.25rem;
    }
}

/* Rand-Rhythmus: kein doppelter Abstand am Anfang/Ende des ERP-HTML. */
.group-description > :first-child {
    margin-top: 0;
}

.group-description > :last-child {
    margin-bottom: 0;
}

/* Responsive Bilder aus dem ERP-HTML (verhindert Overflow, sanfte Radien).
   Ueberschreibt auch feste width/height-Attribute (<img width=".." height="..">),
   da HTML-Presentational-Hints eine geringere Spezifitaet als Author-CSS haben. */
.group-description img {
    max-width: 100%;
    height: auto;
    border-radius: 12px;
}

/* ERP-Redakteure verschachteln teils Bootstraps .container -> feste Breiten/Padding
   wuerden das Layout in unserer Card sprengen. Hier neutralisieren = normaler Block. */
.group-description .container {
    width: auto;
    max-width: none;
    padding-left: 0;
    padding-right: 0;
    margin-left: 0;
    margin-right: 0;
}

.group-description iframe {
    max-width: 100%;
}

.group-description h1,
.group-description h2,
.group-description h3,
.group-description h4,
.group-description h5 {
    font-weight: 700;
    line-height: 1.25;
    margin-top: 1.5rem;
    margin-bottom: .6rem;
}

.group-description p {
    margin-bottom: 1rem;
}

.group-description ul,
.group-description ol {
    margin-bottom: 1rem;
    padding-left: 1.25rem;
}

/* Breite Tabellen scrollen statt das Layout zu sprengen. */
.group-description table {
    max-width: 100%;
}

/* ==== Datentabelle (.data-table) – Standard-Tabellenkomponente ======================
   Loest das ueber den Shop verstreute Alt-Muster ab (table-responsive card +
   table-borderless + thead.bg-light.text-primary), das in ~18 Views wiederholt wird.

   Aufbau:
     <div class="data-table-wrap data-table-wrap--stack">
       <table class="table table-hover data-table">
         <thead>..</thead>
         <tbody><tr><td data-label="Menge">..</td></tr></tbody>

   Zwei Konventionen, die man kennen muss:
   1) KEIN overflow:hidden auf dem Wrap. Bootstraps .table-responsive setzt
      overflow-x:auto, wodurch overflow-y ebenfalls zu auto wird -> Zellen-Dropdowns
      (Bestand, Wunschliste) werden am Tabellenrand abgeschnitten. Dieselbe Ausnahme
      wie bei .product-list-wrap: ab md Overflow freigeben. Darunter greift der
      Stack-Modus, dort wird kein horizontaler Scroll gebraucht.
   2) Runde Ecken deshalb ueber die Randzellen (border-collapse:separate), NICHT ueber
      overflow:hidden am Wrap.

   Theme-agnostisch: keine Markenfarbe im CSS. Akzente kommen ueber BS-Utilities
   (text-primary, bg-primary) im Markup. */
.data-table-wrap {
    border: 1px solid #e9ecef;
    border-radius: 14px;
    background-color: #fff;
    overflow-x: auto;
}

@media (min-width: 768px) {
    /* siehe (1): Dropdowns in Zellen duerfen nicht klippen.
       NUR fuer den Stack-Modus - dort ist die Tabelle ab md schmal genug, dass kein
       horizontaler Scroll gebraucht wird. Bei einer breiten Tabelle OHNE --stack muss
       der Scroll erhalten bleiben, sonst laeuft sie aus dem Layout. */
    .data-table-wrap--stack {
        overflow: visible;
    }
}

.data-table {
    margin-bottom: 0;
    /* separate + border-spacing:0 -> Radien an den Randzellen wirken (siehe (2)) */
    border-collapse: separate;
    border-spacing: 0;
}

.data-table > thead > tr > th {
    background-color: #f8f9fa;
    color: #495057;
    font-weight: 600;
    font-size: .8125rem;
    letter-spacing: .01em;
    border: 0;
    border-bottom: 2px solid #e9ecef;
    padding: .75rem;
    vertical-align: middle;
    white-space: nowrap;
}

.data-table > tbody > tr > td {
    border: 0;
    border-top: 1px solid #edf0f2;
    padding: .75rem;
    vertical-align: middle;
}

.data-table > tbody > tr:first-child > td {
    border-top: 0;
}

/* Neutrales Hover statt Bootstraps rgba(0,0,0,.075) */
.data-table.table-hover > tbody > tr:hover {
    background-color: #f8f9fa;
}

/* Ecken (siehe (2)) */
.data-table > thead > tr:first-child > th:first-child {
    border-top-left-radius: 13px;
}

.data-table > thead > tr:first-child > th:last-child {
    border-top-right-radius: 13px;
}

.data-table > tbody > tr:last-child > td:first-child {
    border-bottom-left-radius: 13px;
}

.data-table > tbody > tr:last-child > td:last-child {
    border-bottom-right-radius: 13px;
}

/* ---- Zellrollen -------------------------------------------------------------
   Rollen-Klassen statt Inline-Styles. Uebertragbar auf jede Tabelle, im Gegensatz
   zu den an die Artikeltabelle gebundenen data-field-Selektoren. */

/* Zahlen (Preise, Mengen, Summen) fluchten spaltenweise */
.data-table__num,
.data-table > thead > tr > th.data-table__num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.data-table__cell--media {
    width: 96px;
    text-align: center;
}

.data-table__cell--media img {
    max-width: 80px;
    height: auto;
}

.data-table__cell--title {
    font-weight: 500;
}

/* Die Titelzelle formatiert nur ihren Text, NICHT enthaltene Formularfelder.
   Bootstraps .form-control setzt keine font-weight -> das Feld hat die 500/600 der
   Zelle geerbt und wurde faelschlich fett dargestellt. */
.data-table__cell--title .form-control {
    font-weight: 400;
}

/* ---- Dichte-Stufe ----------------------------------------------------------- */
.data-table--compact > thead > tr > th,
.data-table--compact > tbody > tr > td {
    padding: .4rem .5rem;
    font-size: .875rem;
}

/* ---- Sticky-Kopf (lange Listen) ---------------------------------------------
   Braucht einen Scrollport mit Hoehe ODER den Viewport als Scrollport. Auf einem
   Container mit overflow-y:auto OHNE height bleibt es wirkungslos. */
.data-table--sticky-head > thead > tr > th {
    position: sticky;
    top: 0;
    z-index: 2;
}

/* ---- Breite Tabellen: eigener Scrollbereich --------------------------------------
   Fuer Tabellen, die auch auf dem Desktop breiter als das Layout sind (Artikeltabelle
   mit dynamischen Merkmalsspalten). Ergaenzt --stack: Karten unter md, Scroll darueber.

   WARUM max-height, und warum das keine Geschmacksfrage ist:
   position:sticky klebt immer am naechsten SCROLLENDEN Vorfahren. Sobald ein Wrap
   overflow-x:auto traegt, wird er dieser Vorfahre - und zwar unvermeidlich: nach
   CSS-Spec wird overflow-y zwangsweise zu auto, wenn overflow-x nicht visible ist.
   Ein Wrap ohne Hoehe kann aber nie vertikal scrollen -> scrollTop bleibt 0 -> der
   sticky Kopf bewegt sich nie und ist faktisch wirkungslos. Genau das war der Zustand
   der Artikeltabelle. Erst eine Hoehenbegrenzung macht den Wrap zu einem echten
   Scrollport und den Kopf damit wirksam. */
@media (min-width: 768px) {
    .data-table-wrap--scroll {
        overflow: auto;
        max-height: 70vh;
    }

    /* Schlaegt die overflow:visible-Regel von --stack, wenn beide kombiniert sind. */
    .data-table-wrap--stack.data-table-wrap--scroll {
        overflow: auto;
    }
}

/* ==== Stack-Modus: Zeilen werden unter md zu Karten ==============================
   Generalisiert das bereits produktiv erprobte Muster aus ArticleListTable
   (#article_table-Media-Query) und macht es wiederverwendbar.

   Der Modifier sitzt am WRAP (nicht an der Tabelle), damit Rahmen/Radius des Wraps
   mit umgeschaltet werden - im Kartenmodus traegt jede Zeile den Rahmen.
   Zur Layout-Technik (Flex + order statt Float) siehe den Kommentar an der tr-Regel. */
@media (max-width: 767.98px) {
    .data-table-wrap--stack {
        border: 0;
        border-radius: 0;
        background-color: transparent;
        overflow: visible;
    }

    .data-table-wrap--stack .data-table,
    .data-table-wrap--stack .data-table > tbody {
        display: block;
    }

    .data-table-wrap--stack .data-table > thead {
        display: none;
    }

    /* Flex statt Block-Float: nur so laesst sich das Bild per order neben den Titel
       nach OBEN holen. Mit float:right beginnt das Bild erst an seiner DOM-Position
       (nach Artikelnr. und Bezeichnung) und landet mitten in der Karte.
       Flex ist hier unbedenklich, obwohl grid es nicht waere: die Spalten werden
       BEDINGT gerendert (Preisrechte, Bestand, Treueshop) - fehlende Zellen fallen
       bei Flex einfach weg, waehrend ein festes grid-template verrutschen wuerde. */
    .data-table-wrap--stack .data-table > tbody > tr {
        display: flex;
        flex-wrap: wrap;
        align-items: flex-start;
        background-color: #fff;
        border: 1px solid #dee2e6;
        border-radius: .5rem;
        box-shadow: 0 1px 2px rgba(0, 0, 0, .04);
        margin: 0 0 .75rem 0;
        padding: .5rem .85rem;
    }

    /* !important schlaegt Inline-Breiten aus dem Alt-Markup (min-width/max-width an
       Zellen), die das Stapeln sonst blockieren. */
    .data-table-wrap--stack .data-table > tbody > tr > td {
        display: block;
        flex: 0 0 100%;
        width: auto !important;
        min-width: 0 !important;
        max-width: none !important;
        border: 0;
        padding: .3rem 0;
    }

    /* Spaltenname als Feldlabel - Text kommt aus dem data-label-Attribut */
    .data-table-wrap--stack .data-table > tbody > tr > td[data-label]::before {
        content: attr(data-label);
        display: block;
        margin-bottom: .15rem;
        font-size: .7rem;
        text-transform: uppercase;
        letter-spacing: .03em;
        color: #6c757d;
    }

    /* Titelzelle ist die Karten-Ueberschrift -> Label waere Dopplung.
       order:-2 holt sie an den Anfang der Karte (oben links). */
    .data-table-wrap--stack .data-table > tbody > tr > td.data-table__cell--title {
        flex: 1 1 auto;
        order: -2;
        font-size: 1rem;
        font-weight: 600;
    }

    .data-table-wrap--stack .data-table > tbody > tr > td.data-table__cell--title::before {
        display: none;
    }

    /* Im Kartenmodus ist die Bezeichnung die Ueberschrift -> etwas praesenter als in
       der Tabellenzeile (dort traegt sie .95rem/500). */
    .data-table-wrap--stack .data-table > tbody > tr > td.data-table__cell--title .vp-cart-desc {
        font-size: 1rem;
        font-weight: 600;
    }

    /* Bild als Thumbnail oben rechts, direkt neben dem Titel (order:-1). */
    .data-table-wrap--stack .data-table > tbody > tr > td.data-table__cell--media {
        flex: 0 0 80px;
        order: -1;
        width: 80px !important;
        max-width: 40% !important;
        margin: 0 0 .4rem .6rem;
        padding-top: 0;
        text-align: center;
    }

    .data-table-wrap--stack .data-table > tbody > tr > td.data-table__cell--media img {
        max-width: 100%;
        border-radius: .25rem;
    }

    /* Zahlen im Kartenmodus linksbuendig - ohne Spalte ergibt rechtsbuendig keinen Sinn */
    .data-table-wrap--stack .data-table > tbody > tr > td.data-table__num {
        text-align: left;
    }

    /* Dasselbe fuer zentrierte Datenzellen (Bestand): in der Tabelle ist die Zentrierung
       richtig, in der Karte gibt es keine Spalte, gegen die zentriert werden koennte -
       Beschriftung und Wert standen dort mittig, waehrend alle Nachbarfelder links
       fluchten. Ausgenommen die Bildzelle, die bewusst ein zentriertes Thumbnail bleibt.
       !important ist noetig, weil Bootstraps .text-center-Utility selbst !important setzt. */
    .data-table-wrap--stack .data-table > tbody > tr > td.text-center:not(.data-table__cell--media) {
        text-align: left !important;
    }

    /* Aktionen als letzter Block der Karte, abgesetzt vom Rest.
       (clear:right entfaellt - die Zeile ist kein Float-Kontext mehr, sondern Flex.) */
    .data-table-wrap--stack .data-table > tbody > tr > td.data-table__cell--actions {
        order: 1;
        margin-top: .35rem;
        padding-top: .5rem;
        border-top: 1px solid #f1f3f5;
    }

    .data-table-wrap--stack .data-table > tbody > tr > td.data-table__cell--actions > .d-flex {
        flex-wrap: wrap;
    }

    /* Bestellzelle (Mengenfeld + Absende-Button, Favoritenliste): direkt VOR den Aktionen,
       damit "Menge waehlen -> in den Warenkorb -> loeschen" im Kartenfuss zusammenhaengt.
       Ohne eigenen order-Wert stuende sie zwischen Preis und Bestand, also mitten in den
       Datenfeldern. Der Rahmen sitzt hier, die Aktionszelle darunter bekommt keinen
       zweiten - sonst entstuenden zwei Trennlinien direkt untereinander. */
    .data-table-wrap--stack .data-table > tbody > tr > td.data-table__cell--order {
        order: 1;
        margin-top: .35rem;
        padding-top: .5rem;
        border-top: 1px solid #f1f3f5;
    }

    .data-table-wrap--stack .data-table > tbody > tr > td.data-table__cell--order + td.data-table__cell--actions {
        margin-top: 0;
        padding-top: .25rem;
        border-top: 0;
    }

    .data-table-wrap--stack .data-table > tbody > tr > td.data-table__cell--order > .d-flex,
    .data-table-wrap--stack .data-table > tbody > tr > td.data-table__cell--order form > .d-flex {
        flex-wrap: wrap;
    }

    /* Platzhalterzellen (Unterposition: leere Aktions-/Punktezelle) sind im Kartenmodus
       ueberfluessig - ohne Spaltenraster gibt es nichts auszurichten, sie wuerden nur
       eine leere Zeile samt Trennlinie erzeugen. Auf dem Desktop bleiben sie stehen,
       weil dort die Spaltenzahl zur Kopfzeile passen muss. */
    .data-table-wrap--stack .data-table > tbody > tr > td:empty {
        display: none;
    }
}

/* ==== Doppelte Scroll-Leiste (breite Tabellen) ====================================
   Eine 16px hohe Attrappe ueber der Tabelle, deren .scroll-content per JS auf die
   Tabellenbreite gesetzt wird. Der negative margin-bottom zieht sie optisch an die
   Tabelle heran. Beide Leisten werden per JS synchronisiert.
   Generisch gehalten - das Muster passt auf jede horizontal scrollende Tabelle. */
/* Abstand liegt am WRAPPER, nicht am inneren Tabellen-Wrap. Grund: die Scroll-Attrappe
   darueber traegt margin-bottom:-16px; ein mt am inneren Wrap kollabiert damit auf 0,
   waehrend das mb unten voll wirkt - oben und unten waren dadurch unterschiedlich weit
   von den Pagern entfernt. Am Wrapper ist der Abstand symmetrisch und unabhaengig
   vom Negativ-Margin-Trick im Inneren. */
.table-scroll-wrapper {
    position: relative;
    margin-top: 1rem;
    margin-bottom: 1rem;
}

.scrollable-header {
    overflow-x: auto;
    height: 16px;
    margin-bottom: -16px; /* gleiche Hoehe wie die Scroll-Leiste */
}

.scroll-content {
    height: 1px;
}

@media (max-width: 767.98px) {
    /* Im Kartenmodus gibt es keinen horizontalen Scroll -> Attrappe ausblenden. */
    .scrollable-header {
        display: none;
    }
}

/* ==== Artikeltabelle (Produktseite) ===============================================
   Nutzt .data-table + --stack + --scroll + --sticky-head. Hier stehen nur die
   Abweichungen, die aus ihrer Sonderstellung folgen: dynamische Merkmalsspalten,
   Filter-Dropdowns im Kopf und das Zubehoer-Accordion.

   NICHT migrierbar (dokumentiert, damit es niemand erneut versucht):
   - Preis+Bestand teilen eine Zelle, Menge+alle Aktionen ebenfalls. Das Warenkorb-
     <form> umspannt Mengenfeld und Button; ein <form> ueber zwei <td> gibt es in
     HTML nicht. Deshalb kein .data-table__cell--actions.
   - Die <th> enthalten interaktive Filter-Dropdowns, die per JS fix positioniert
     werden und Button+Menue als DIREKTE Kinder erwarten. */

/* Merkmalsspalten duerfen umbrechen. Der Standard setzt am Kopf white-space:nowrap;
   bei nach oben unbegrenzt vielen Merkmalsspalten ist genau das ein Haupttreiber der
   Tabellenbreite. Die fixen Spalten behalten nowrap. */
#article_table > thead > tr > th[data-field="ArticleFeature"] {
    white-space: normal;
    min-width: 7rem;
}

/* Kopf hebt sich beim vertikalen Scrollen des Wraps ab (Hintergrund und Unterkante
   kommen bereits aus .data-table). */
#article_table > thead > tr > th {
    box-shadow: 0 2px 2px -1px rgba(0, 0, 0, .06);
}

/* Bezeichnungsspalte: in der Tabelle bewusst schmaler und kleiner gesetzt, damit die
   Merkmalsspalten Platz behalten. Im Kartenmodus wird sie zur Ueberschrift (siehe
   Media-Query weiter unten) - deshalb steht die Groesse hier und nicht inline. */
@media (min-width: 768px) {
    #article_table > tbody > tr > td.article-name-cell {
        width: 15%;
        font-size: .85rem;
    }
}

/* Preis etwas praesenter als der Rest der Zeile. */
#article_table td[data-field="decPrice"] h5 {
    font-size: 1.05rem;
    margin-bottom: 0;
}

/* Zahlen in Preis- und Mengenzelle fluchten. Bewusst OHNE .data-table__num, weil
   beide Zellen zusammengesetzt sind (Preis+Bestand bzw. Menge+Einheit+Aktionen) -
   rechtsbuendig waere dort falsch, tabellarische Ziffern sind trotzdem richtig. */
#article_table td[data-field="decPrice"],
#article_table td[data-field="AddToCart"] {
    font-variant-numeric: tabular-nums;
}

@media (min-width: 768px) {
    /* Erste Spalte (Artikelnummer) beim horizontalen Scrollen fixieren - bei vielen
       Merkmalsspalten geht sonst die Zuordnung Zeile<->Artikel verloren.
       Braucht einen eigenen Hintergrund, sonst scrollen die uebrigen Zellen sichtbar
       darunter durch.
       ACHTUNG: sticky erzeugt einen Stacking-Context. Das Artikel-Detail-Modal liegt in
       genau dieser Zelle -> der Modal-Reparenting-Hack in ArticleListTable.cshtml deckt
       deshalb die ganze Tabelle ab, nicht nur .accessory-content. */
    #article_table > thead > tr > th:first-child,
    #article_table > tbody > tr:not(.accessory-row) > td:first-child {
        position: sticky;
        left: 0;
    }

    #article_table > thead > tr > th:first-child {
        /* ueber den Body-Zellen, aber unter dem geoeffneten Filter-Menue (z-index 1030) */
        z-index: 3;
    }

    /* Die fixierte Zelle ERBT den Zeilenhintergrund, statt einen eigenen zu setzen.
       Sonst uebermalt sie die Trefferzeilen-Markierung: .bg-success-opacity traegt zwar
       !important, sitzt aber am <tr> - gegen eine Farbe auf dem <td> hilft das nicht,
       weil es zwei verschiedene Elemente sind. Genau das war passiert: markierte Zeile
       gruen, erste Spalte weiss.
       Damit inherit etwas zu erben hat, braucht die Zeile einen Default. */
    #article_table > tbody > tr:not(.accessory-row) {
        background-color: #fff;
    }

    #article_table > tbody > tr:not(.accessory-row) > td:first-child {
        z-index: 1;
        background-color: inherit;
    }

    /* Hover ebenfalls an der ZEILE, damit die fixierte Zelle ihn miterbt. */
    #article_table.table-hover > tbody > tr:not(.accessory-row):hover {
        background-color: #f8f9fa;
    }
}

/* Artikel-Thumbnail. Loest zwei widerspruechliche Inline-Strategien ab, die fuer
   denselben Slot nebeneinander standen (max/min-height:80px gegen max/min-width:80px).
   Feste Box + contain: das Bild bestimmt die Zeilenhoehe nicht mehr mit, unabhaengig
   von seinem Seitenverhaeltnis. Die width/height-Attribute im Markup reservieren den
   Platz schon vor dem Laden - sonst springt das Layout, und weil die Tabellenbreite
   daran haengt, laeuft auch die obere Scroll-Leiste kurz falsch. */
.article-thumb {
    width: 80px;
    height: 80px;
    object-fit: contain;
}

/* ---- Zubehoer-Accordion ------------------------------------------------------- */
.accessory-toggle {
    cursor: pointer;
    border: 0; /* <button> als Badge: UA-Border entfernen */
    transition: box-shadow .15s ease;
}

/* Affordanz; die Hover-Farbe liefert die Theme-Klasse vomberg-custom-hover-btn-green */
.accessory-toggle:hover {
    box-shadow: 0 1px 3px rgba(0, 0, 0, .25);
}

.accessory-toggle .accessory-chevron {
    transition: transform .2s ease;
    margin-right: 2px;
}

.accessory-toggle[aria-expanded="true"] .accessory-chevron {
    transform: rotate(180deg);
}

.accessory-row > td {
    background-color: #f8f9fa;
    /* Haengt visuell an seiner Artikelzeile -> kein Trenner dazwischen. */
    border-top: 0;
}

.accessory-panel {
    margin: 0 .5rem .5rem 1.75rem;
    padding: .75rem 1rem;
    border-left: 3px solid #dee2e6;
    /* Bei sehr breiter Tabelle nicht ueber die ganze Breite ziehen, sondern links
       sichtbar fixieren. ACHTUNG: erzeugt einen Stacking-Context - deshalb der
       Modal-Reparenting-Hack in ArticleListTable.cshtml. Eins ohne das andere
       entfernen bricht die Zubehoer-Modals. */
    position: sticky;
    left: 0;
    max-width: 960px;
}

/* Reservierter Platz beim Nachladen -> kein Hoehen-/Scroll-Springen */
.accessory-loading {
    min-height: 90px;
}

@media (max-width: 767.98px) {
    /* Bezeichnung ist die Karten-Ueberschrift. Die Groesse steht hier und NICHT als
       inline style am <td>: ein Inline-Style schlaegt die Stack-Regel des Standards
       (1rem/600), die kein !important traegt - die Ueberschrift blieb dadurch kleiner
       als der Rest der Karte. */
    .data-table-wrap--stack #article_table > tbody > tr > td.data-table__cell--title {
        font-size: 1rem;
    }

    /* Preis hervorheben. Stand vor dem Umbau in der Inline-Media-Query der View und
       war beim Verschieben ersatzlos entfallen. */
    .data-table-wrap--stack #article_table > tbody > tr > td[data-field="decPrice"] {
        font-weight: 600;
    }

    /* Aktionszelle: Der Standard loest das ueber .data-table__cell--actions - die traegt
       die Artikeltabelle bewusst nicht, weil Menge und Aktionen sich EINE Zelle teilen
       (das Warenkorb-<form> umspannt beide). Also hier direkt am data-field.
       Ohne flex-wrap laufen Stepper + Einheit + Button auf schmalen Geraeten aus der
       Karte; das inline min-width:200px wird vom Stack-Modus per !important geloescht. */
    .data-table-wrap--stack #article_table > tbody > tr > td[data-field="AddToCart"] > .d-flex {
        flex-wrap: wrap;
    }

    .data-table-wrap--stack #article_table > tbody > tr > td[data-field="AddToCart"] .form-inline {
        flex-wrap: wrap;
    }

    /* Merkmale als kompakte "Name: Wert"-Zeilen statt Label ueber Wert - bei vielen
       Merkmalen waere die Karte sonst doppelt so hoch. Ueberschreibt die
       ::before-Regel des Stack-Modus. */
    .data-table-wrap--stack #article_table > tbody > tr > td[data-field="sArticleFeature"] {
        padding: .1rem 0;
    }

    .data-table-wrap--stack #article_table > tbody > tr > td[data-field="sArticleFeature"]::before {
        content: attr(data-label) ": ";
        display: inline;
        margin: 0 .35rem 0 0;
    }

    /* Zubehoerzeile ist keine Karte, sondern haengt unter ihrer Artikelkarte. */
    .data-table-wrap--stack #article_table > tbody > tr.accessory-row {
        display: block;
        background-color: transparent;
        border: 0;
        border-radius: 0;
        box-shadow: none;
        margin: -.5rem 0 .75rem 0;
        padding: 0;
    }

    .data-table-wrap--stack #article_table > tbody > tr.accessory-row > td {
        padding: 0;
    }

    .accessory-panel {
        margin-left: 0;
    }
}

/* ==== Warenkorb-Slider (MiniCart) =================================================
   Aus dem Inline-<style> von MiniCart.cshtml hierher gezogen. Klassennamen bewusst
   unveraendert, damit Markup und JS nicht mitwandern muessen.

   Drei-Zonen-Aufbau (Kopf / scrollender Body / Fuss): Summe und CTA bleiben dadurch
   immer sichtbar, auch mobil und bei vielen Positionen - konzeptionell besser als ein
   sticky Summenpanel, deshalb unveraendert uebernommen. */
.cart-sidebar {
    position: fixed;
    top: 0;
    right: 0;
    width: 400px;
    height: 100%;
    background-color: #fff;
    box-shadow: -2px 0 16px rgba(0, 0, 0, .12);
    transform: translateX(100%);
    transition: transform .3s ease, visibility .3s ease;
    z-index: 1050;
    display: flex;
    flex-direction: column;
    /* visibility nimmt den geschlossenen Slider aus der Tab-Reihenfolge UND aus dem
       Screenreader-Baum. Vorher war er nur per translateX weggeschoben: Tab lief durch
       den kompletten Warenkorb inklusive Bestellabschluss-CTA, und Screenreader lasen
       ihn auf jeder Seite des Shops mit. */
    visibility: hidden;
}

.cart-sidebar.show {
    transform: translateX(0);
    visibility: visible;
}

.cart-sidebar__head {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1rem 1.1rem;
    border-bottom: 1px solid #edf0f2;
}

.cart-sidebar__body {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: .5rem 1.1rem 1rem;
}

.cart-sidebar__foot {
    flex: 0 0 auto;
    padding: .9rem 1.1rem 1.1rem;
    border-top: 1px solid #edf0f2;
    background-color: #fff;
}

.cart-overlay {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, .5);
    z-index: 1049;
}

.cart-overlay.show {
    display: block;
}

.close-miniCart {
    cursor: pointer;
    line-height: 1;
}

body.cart-open {
    overflow: hidden;
}

/* Stammt aus dem MiniCart-Partial und wirkte von dort aus auf JEDE Seite des Shops.
   Bewusst unveraendert uebernommen statt entfernt: die Regel kaschiert seit Langem
   horizontale Overflows, ein Wegfall wuerde sie auf einen Schlag sichtbar machen.
   TODO: Ursachen einzeln beheben, dann diese Regel streichen. */
body {
    overflow-x: hidden;
}

.cart-line {
    padding: .6rem 0;
    border-bottom: 1px solid #f1f3f5;
}

.cart-line:last-child {
    border-bottom: 0;
}

.cart-line__img {
    min-width: 64px;
    max-width: 64px;
}

/* ==== Aktionszeile der Produktkachel ==============================================
   Bestand, Favoritenliste, Menge, Warenkorb. Vorher standen dort vier verschiedene
   Behandlungen nebeneinander: ein nacktes Icon (Bestand), ein grauer btn-light-Kasten
   mit eigenen ml-2/mr-2-Margins (Favoriten), der Stepper und der gruene Button - dazu
   ein margin-left:auto am Formular, das mitten in die Zeile eine Luecke riss.

   Jetzt: die beiden Nebenaktionen links als gleich grosse, zurueckgenommene
   Icon-Buttons, die Hauptaktion (Menge + Warenkorb) als Gruppe rechts. */
.tile-actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .4rem;
}

/* Bestand und Favoritenliste sind gleichrangige Nebenaktionen -> gleiche Flaeche,
   gleicher Hover. Der Selektor greift auch den Button aus StockLevel.cshtml, ohne
   dass das geteilte Partial angefasst werden muss. */
/* Zwei Pfade, bewusst getrennt statt eines pauschalen Nachfahren-Selektors:
   - Bestand liegt tief verschachtelt (.form-group > .StockLevel > ...), je nach
     shtStockLevel mit oder ohne .dropdown -> Nachfahren-Selektor noetig.
   - Favoriten NUR der Toggle als direktes Kind. Ein pauschales
     ".tile-actions__side .btn" wuerde auch die "Hinzufuegen"-Buttons IM
     Wunschlisten-Menue treffen und diese auf 2.25rem quadratisch stauchen. */
.tile-actions__side > .form-group .btn,
.tile-actions__side > .dropdown > .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    padding: 0;
    margin: 0;
    border: 0;
    border-radius: 8px;
    background-color: transparent;
    transition: background-color .15s ease;
}

.tile-actions__side > .form-group .btn:hover,
.tile-actions__side > .dropdown > .btn:hover {
    background-color: #f1f3f5;
}

/* Deaktivierter Bestands-Button (shtStockLevel == 2) soll nicht wie klickbar wirken. */
.tile-actions__side > .form-group .btn:disabled,
.tile-actions__side > .form-group .btn.disabled {
    background-color: transparent;
    opacity: 1;
}

/* Menge und Warenkorb bilden das rechte Ende der Zeile.
   NUR margin-left: auto - display/gap/align waeren wirkungslos, weil das <form>
   als einziges Kind ein .form-group > .form-inline enthaelt und die eigentlichen
   Elemente zwei Ebenen tiefer liegen. Das Layout dort macht Bootstraps
   .form-inline. */
.tile-actions__main {
    margin-left: auto;
    margin-bottom: 0;
}

/* Das VPE-Vorschlagsmenue haengt am Stepper und erbt Bootstraps min-width von
   10rem. Der kompakte Stepper misst nur ~6.7rem und sitzt am rechten Kartenrand -
   das Menue ragte dadurch ueber die Kachel hinaus. Rechtsbuendig ausrichten und
   auf die Breite des Steppers begrenzen. */
.tile-actions__main .qty-stepper > .dropdown-menu {
    min-width: 100%;
    right: 0;
    left: auto;
}

/* Entfernen-Aktion der Slider-Zeile: runder Icon-Button statt rotem Textlink.
   Im Ruhezustand neutral-grau und zurueckgenommen - Loeschen soll auffindbar sein,
   aber nicht dauerhaft mit Bezeichnung und Preis um Aufmerksamkeit konkurrieren.
   Erst bei Hover/Fokus faerbt es sich in die Gefahrenfarbe ein.

   Die Toenung laeuft ueber den currentColor-Trick (::before + niedrige opacity):
   die Farbe liefert die text-danger-Utility am Element, nicht ein fester Hex-Wert -
   damit bleibt es theme-agnostisch. */
.cart-line__remove {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border: 0;
    border-radius: 50rem;
    background-color: transparent;
    font-size: .95rem;
    line-height: 1;
    color: #adb5bd;
    cursor: pointer; /* nacktes <button> ohne .btn haette cursor: default */
    transition: color .15s ease;
}

.cart-line__remove::before {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    border-radius: 50rem;
    background-color: currentColor;
    opacity: 0;
    transition: opacity .15s ease;
}

.cart-line__remove > i {
    position: relative; /* ueber der Toenungsflaeche */
}

.cart-line__remove:hover,
.cart-line__remove:focus-visible {
    color: #dc3545; /* Bootstrap $danger - semantisch, keine Markenfarbe */
}

.cart-line__remove:hover::before,
.cart-line__remove:focus-visible::before {
    opacity: .12;
}

.cart-line__remove:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 2px;
}

/* Keine eigene Breitenregel fuer den Slider - er nutzt .qty-stepper--sm.
   Dort sind es zwar ebenfalls 3.5rem, aber bei .8125rem Schrift statt 1rem:
   dieselben Ziffern brauchen weniger Platz, der frueher verworfene Abschnitt
   vierstelliger Mengen entsteht dadurch nicht. */

@media (max-width: 767.98px) {
    .cart-sidebar {
        width: 100%;
        max-width: 100%;
    }
}

/* ==== Leerzustand (Warenkorb, Favoritenliste, leere Listen) ======================= */
.data-table-empty {
    padding: 2.5rem 1rem;
    text-align: center;
    border: 1px dashed #dee2e6;
    border-radius: 14px;
    background-color: #f8f9fa;
    color: #6c757d;
}

.data-table-empty__icon {
    font-size: 2.5rem;
    color: #adb5bd;
    margin-bottom: .75rem;
}

/* ---- Artikelnummer & Bezeichnung in der Warenkorbzeile --------------------------
   Hierarchie: die BEZEICHNUNG ist der Anker (ueber sie erkennt man die Position
   wieder), die Artikelnummer ist eine Kennung. Vorher waren beide gleich gewichtet
   und die Zeile hatte keinen Blickfang. */

/* Kennung: klein, gedaempft, fluchtende Ziffern (untereinander stehende Nummern
   lassen sich so spaltenweise vergleichen). */
.cart-article-id {
    font-size: .8rem;
    color: #6c757d;
    font-variant-numeric: tabular-nums;
    letter-spacing: .02em;
}

/* Bezeichnung: leicht groesser und kraeftiger als der Rest der Zeile.
   Loest das frühere Inline-style="max-width:350px" ab, das im Stack-Modus stoerte. */
.vp-cart-desc {
    max-width: 350px;
    font-size: .95rem;
    font-weight: 500;
    color: #212529;
}

@media (min-width: 768px) {
    /* Auf zwei Zeilen begrenzen, damit lange ERP-Bezeichnungen die Zeilenhoehe nicht
       sprengen. Der vollstaendige Text haengt als title am Element.
       Nur ab md: im Kartenmodus ist die Bezeichnung die Ueberschrift und es ist
       genug Platz - dort soll nichts abgeschnitten werden. */
    .vp-cart-desc {
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
    }
}

@media (max-width: 767.98px) {
    .vp-cart-desc {
        max-width: none;
    }
}

/* ---- Zurueckgenommene Eingabefelder (Kunden-Artikelnr., Positionskommission) -----
   Optionale Metadaten, die die meisten Nutzer nie fuellen. Mit vollem Rahmen zogen
   sie mehr Aufmerksamkeit als Bezeichnung und Preis. Deshalb rahmenlos mit feiner
   gestrichelter Grundlinie (signalisiert "hier kann man schreiben"); der volle
   Rahmen erscheint erst bei Hover/Fokus. */
.cart-ghost-input.form-control {
    border: 0;
    border-bottom: 1px dashed #dee2e6;
    border-radius: 0;
    background-color: transparent;
    padding-left: 0;
    padding-right: 0;
    box-shadow: none;
    color: #495057;
    transition: border-color .15s ease, background-color .15s ease;
}

.cart-ghost-input.form-control:hover {
    border-bottom-color: #adb5bd;
}

.cart-ghost-input.form-control:focus {
    border-bottom-style: solid;
    border-bottom-color: #6c757d;
    background-color: #fff;
    /* Dokumentiertes Fokus-Muster des Projekts (theme-agnostisch ueber currentColor). */
    outline: 2px solid currentColor;
    outline-offset: 2px;
}

.cart-ghost-input.form-control::placeholder {
    color: #adb5bd;
}

/* ==== Mengen-Stepper (Warenkorb, MiniCart, Favoritenliste) =========================
   Umschliesst das bestehende Mengen-Input; die -/+ Buttons setzen nur den Wert und
   feuern anschliessend 'change'. Damit laeuft der bestehende Postback
   (onchange="this.form.submit()") unveraendert weiter - kein AJAX, keine neue Action.

   Achtung: Im VPE-Fall (shtNoPackageBreak == 1) traegt das Input zusaetzlich
   data-toggle="dropdown" fuer das Mengen-Vorschlagsmenue; der Stepper ist dann selbst
   der .dropdown-Container. Deshalb KEIN overflow:hidden - das wuerde das Vorschlagsmenue
   abschneiden (gleiche Regel wie bei .data-table-wrap und .product-list-wrap). Die runden
   Ecken kommen stattdessen von den Randkindern. */
.qty-stepper {
    display: inline-flex;
    align-items: stretch;
    border: 1px solid #dee2e6;
    border-radius: 8px;
    background-color: #fff;
}

.qty-stepper > :first-child {
    border-top-left-radius: 7px;
    border-bottom-left-radius: 7px;
}

.qty-stepper > :last-child {
    border-top-right-radius: 7px;
    border-bottom-right-radius: 7px;
}

/* Das Vorschlagsmenue ist Kind des Flex-Containers - es darf weder Flex-Item-Groessen
   erben noch die Rand-Radien der Randkinder abbekommen. */
.qty-stepper > .dropdown-menu {
    flex: none;
    border-radius: 12px;
}

.qty-stepper__btn {
    border: 0;
    background-color: #f8f9fa;
    color: #495057;
    width: 2rem;
    flex: 0 0 2rem;
    line-height: 1;
    transition: background-color .15s ease;
}

.qty-stepper__btn:hover {
    background-color: #f1f3f5;
}

.qty-stepper__btn:active {
    background-color: #e2e6ea;
}

.qty-stepper__btn:disabled {
    color: #adb5bd;
    background-color: #f8f9fa;
}

.qty-stepper__btn:focus {
    outline: 2px solid currentColor;
    outline-offset: -2px;
}

/* Das Input sitzt zwischen den Buttons - eigener Rahmen/Radius waere doppelt */
.qty-stepper .form-control {
    border: 0;
    border-left: 1px solid #e9ecef;
    border-right: 1px solid #e9ecef;
    border-radius: 0;
    box-shadow: none;
    text-align: center;
    /* Breit genug fuer realistische Mengen inkl. Nachkommastellen ("1234,5").
       3.5rem hat vierstellige Werte abgeschnitten. */
    width: 5rem;
    min-width: 0;
    font-variant-numeric: tabular-nums;
}

/* Native Spin-Buttons ausblenden - der Stepper bringt eigene -/+ Buttons mit,
   sonst stehen beide Bedienelemente nebeneinander. */
.qty-stepper .form-control[type="number"] {
    -moz-appearance: textfield;
}

.qty-stepper .form-control[type="number"]::-webkit-outer-spin-button,
.qty-stepper .form-control[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

/* Mengeneinheit direkt am Stepper */
.qty-stepper__unit {
    display: inline-flex;
    align-items: center;
    padding: 0 .5rem;
    background-color: #f8f9fa;
    border-left: 1px solid #e9ecef;
    color: #6c757d;
    font-size: .8125rem;
    white-space: nowrap;
}

/* ---- Kompakte Variante -----------------------------------------------------------
   Fuer enge Kontexte: Produktkachel/Kategoriezeile und die Zeile im Warenkorb-Slider.
   Die Basis braucht 2 + 5 + 2 = 9rem plus Einheit und sprengt dort das Layout.

   Verschmaelert wird NICHT einfach das Feld - genau das hat schon einmal vierstellige
   Mengen abgeschnitten. Stattdessen sinkt die Schriftgroesse, wodurch dieselben Ziffern
   weniger Platz brauchen: bei .8125rem passt "1234,5" in 3.5rem statt in 5rem.
   Ergebnis rund 6.7rem statt 9rem. */
.qty-stepper--sm {
    font-size: .8125rem;
}

.qty-stepper--sm .qty-stepper__btn {
    width: 1.6rem;
    flex: 0 0 1.6rem;
    font-size: .75rem;
}

.qty-stepper--sm .form-control {
    width: 3.5rem;
    height: auto;
    padding: .25rem .25rem;
    font-size: .8125rem;
}

.qty-stepper--sm .qty-stepper__unit {
    padding: 0 .35rem;
    font-size: .75rem;
}

/* ==== Summen-Panel (Warenkorb / Bestellabschluss) ==================================
   Laeuft ab xl beim Scrollen mit, damit die Summe und der CTA bei langen
   Positionslisten sichtbar bleiben. Darunter steht das Panel ohnehin ueber der
   Liste (order-Klassen im Markup). */
.cart-summary {
    border: 1px solid #e9ecef;
    border-radius: 14px;
    background-color: #fff;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .04);
}

@media (min-width: 1200px) {
    /* Sticky am WRAPPER (Karte + Freitext + Button), nicht an der Karte allein: ein
       klebendes Element verschiebt sich gegenueber seiner Normalposition und ueberlagert
       dabei nachfolgende Geschwister - der Text darunter verschwand.

       top: 6rem statt 1rem, weil .site-header--sticky bei top:0 mit z-index:1030 steht;
       bei 1rem schob sich das Panel unter den Header. 6rem ist der im Projekt bereits
       etablierte Header-Freiraum (siehe scroll-margin-top der Sprungmarken weiter oben). */
    .cart-summary-sticky {
        position: sticky;
        top: 6rem;
        /* Ohne max-height ist der Fuss des Panels unerreichbar, sobald es hoeher wird als
           der Viewport - moeglich durch ERP-Freitext + AGB-Hinweis + Fehlermeldung auf
           einem 768px-Laptop. Eigener Scrollbereich ist hier unbedenklich: im Summen-Panel
           stecken keine Dropdowns, die geclippt werden koennten. */
        max-height: calc(100vh - 7rem);
        overflow-y: auto;
    }
}

.cart-summary__head {
    padding: .75rem 1rem;
    border-bottom: 1px solid #edf0f2;
    text-align: center;
}

.cart-summary__body {
    padding: 1rem;
}

/* Summenzeilen: Label links gedaempft, Wert rechts mit fluchtenden Ziffern */
/* Trennlinien ueber das Geschwister-Muster statt border-bottom an jeder Zeile:
   sonst treffen im Netto-Auftrag (B2B-Regelfall) die border-bottom der
   Logistikpauschale und die border-top der --total-Zeile aufeinander -
   1px-Linie, 4px Luft, 2px-Linie. Im Brutto-Auftrag faellt es nicht auf, weil
   davor eine --minor-Zeile ohne Rahmen steht. */
.cart-summary__row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    padding: .4rem 0;
}

.cart-summary__label {
    color: #6c757d;
    font-size: .875rem;
}

.cart-summary__value {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Schlusszeile (Brutto bzw. Punkte-Saldo) deutlich abgesetzt */
.cart-summary__row + .cart-summary__row {
    border-top: 1px solid #f1f3f5;
}

/* Muss den Geschwister-Selektor darueber schlagen - deshalb ebenfalls als
   Geschwister-Regel geschrieben (gleiche Spezifitaet, spaeter im Stylesheet). */
.cart-summary__row + .cart-summary__row--total,
.cart-summary__row--total {
    border-bottom: 0;
    border-top: 2px solid #e9ecef;
    margin-top: .25rem;
    padding-top: .6rem;
}

.cart-summary__row--total .cart-summary__label {
    color: #212529;
    font-size: 1rem;
    font-weight: 600;
}

.cart-summary__row--total .cart-summary__value {
    font-size: 1.125rem;
    font-weight: 700;
}

/* Nachweiszeilen unterhalb der Schlusszeile (im Netto-Auftrag: Steuer und Brutto).
   Muessen sichtbar bleiben, sollen aber nicht mit dem Hauptbetrag konkurrieren. */
.cart-summary__row--minor {
    border-bottom: 0;
    padding-top: .2rem;
    padding-bottom: .2rem;
}

/* Farbe NICHT hier zuruecknehmen: die Theme-Dateien setzen .text-primary mit
   !important, dagegen kaeme diese Regel nicht an. Die Nachweiszeilen tragen im
   Markup deshalb gar kein text-primary. */
.cart-summary__row--minor .cart-summary__label,
.cart-summary__row--minor .cart-summary__value {
    font-size: .8125rem;
    color: #6c757d;
}

.cart-summary__note {
    padding: 0 1rem .75rem;
    font-size: .75rem;
    color: #6c757d;
    text-align: center;
}

/* ==== Hinweispanel (Warenkorb-Freitexte, Schnellerfassungs-Hinweis) ================
   Ersetzt die frueheren "card shadow-sm"-Kaesten. Neutral getoent statt Karte, damit
   Hinweise nicht wie eigenstaendige Inhaltsblöcke wirken. */
.cart-notice {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .75rem 1rem;
    border: 1px solid #e9ecef;
    border-radius: 14px;
    background-color: #f8f9fa;
    color: #495057;
}

/* Warnvariante: getoenter Rand links statt vollflaechigem Gelb (ruhiger, und der Text
   bleibt auf neutralem Grund lesbar). bg-warning war fuer einen reinen Hinweis zu laut. */
.cart-notice--warning {
    border-left: 4px solid #ffc107;
}

.cart-notice__icon {
    font-size: 1.25rem;
    color: #adb5bd;
    flex: none;
}

.cart-notice--warning .cart-notice__icon {
    color: #d39e00;
}

/* Formularlabel in Warenkorb-Dialogen: frueher "border-bottom" als Trennlinie, was wie
   ein Eingabefeld aussah. Jetzt gedaempfte Beschriftung ueber dem Feld. */
.cart-field-label {
    display: block;
    margin-bottom: .25rem;
    font-size: .8125rem;
    font-weight: 600;
    color: #495057;
}

/* Zeile in der Schnellerfassungs-Uebersicht: neutraler Trenner statt border-primary. */
.cart-entry-row + .cart-entry-row {
    border-top: 1px solid #edf0f2;
}

/* ---- Felder/Texte in der Positionszeile ----------------------------------------
   Ersetzen die frueheren Inline-min-width/max-width, die das Stack-Layout blockierten. */
.cart-field-narrow {
    max-width: 180px;
}

.cart-field-wide {
    min-width: 200px;
}

@media (max-width: 767.98px) {
    .cart-field-narrow,
    .cart-field-wide {
        max-width: none;
        min-width: 0;
    }
}

/* Rein informativer Text (z. B. Positionstext) - frueher ein disabled <input>, das
   wie ein bedienbares Feld aussah. */
.cart-readonly-text {
    padding: .25rem .5rem;
    border-left: 2px solid #e9ecef;
    color: #495057;
    font-size: .875rem;
    /* Explizit normal: die Zelle traegt jetzt --title und wuerde sonst 500/600 vererben. */
    font-weight: 400;
}

/* Nicht aenderbare Menge (Stuecklisten-Unterposition) */
.cart-readonly-qty {
    font-variant-numeric: tabular-nums;
}

/* Vorformatierter ERP-Text (z. B. Stuecklisten-Komponenten): Zeilenumbrueche aus dem
   Backend erhalten. Loest das frühere Inline-style="white-space: pre-line" ab. */
.cart-pre-text {
    white-space: pre-line;
}

/* Punktewert im Treueshop - frueher Inline font-size:1.4rem */
.cart-points {
    font-size: 1.25rem;
}

/* Untergeordnete Zeile (Stuecklisten-Bestandteil): dezent abgesetzt statt bg-light,
   damit sie im Stack-Modus nicht wie eine eigene Karte wirkt. */
.data-table__row--sub > td {
    background-color: #f8f9fa;
}

@media (max-width: 767.98px) {
    .data-table-wrap--stack .data-table > tbody > tr.data-table__row--sub {
        background-color: #f8f9fa;
        border-style: dashed;
    }

    .data-table-wrap--stack .data-table > tbody > tr.data-table__row--sub > td {
        background-color: transparent;
    }
}

/* Zusatzangaben unter Preis/Menge (VPE, Staffel-Hinweise). Die Alt-Klasse
   .blockquote-spezial weiter oben in dieser Datei bleibt unangetastet - hier nur
   die Darstellung innerhalb der Datentabelle beruhigt. */
.data-table .blockquote-spezial {
    font-size: .75rem;
    color: #6c757d;
    line-height: 1.35;
}

/* Icon im Bild-Overlay ("zum Produkt") - frueher Inline font-size:1.1rem, 8x wiederholt */
.cart-img-overlay__icon {
    font-size: 1.1rem;
}

/* ==== Bestandsanzeige (StockLevel, per AJAX nachgeladen) ==========================
   Statusfarben als Klassen statt HTML-Farbnamen im Inline-style. Bewusst neutrale
   Ampel-Semantik (kein Markenblau) - die Aussage ist Verfuegbarkeit, nicht Marke. */
/* em statt rem: das Icon skaliert mit seinem Textkontext. In der Artikeltabelle steht
   es in einem 0.9rem-Button und wirkte mit festen 1.1rem 22% zu gross gegenueber dem
   Text daneben. Im Warenkorb (1rem-Kontext) bleibt die Groesse unveraendert. */
.stock-icon {
    font-size: 1.1em;
}

.stock-icon--available {
    color: #28a745;
}

.stock-icon--limited {
    color: #fd7e14;
}

.stock-icon--none {
    color: #adb5bd;
}

/* Loest die Inline-min-width der Bestands-Dropdowns ab; bricht auf schmalen
   Viewports nicht mehr aus dem Bildschirm. */
.stock-menu {
    min-width: min(250px, calc(100vw - 2rem));
}

.stock-menu__item {
    min-width: 200px;
}

/* Interaktive Variante des neutralen Chips (z. B. "Set-Artikel" oeffnet einen Dialog).
   .hero-chip selbst bleibt bewusst nicht-interaktiv. */
.hero-chip--action {
    border: 0;
    cursor: pointer;
    transition: background-color .15s ease;
}

.hero-chip--action:hover {
    background-color: #e2e6ea;
}

.hero-chip--action:focus {
    outline: 2px solid currentColor;
    outline-offset: 2px;
}

/* ==========================================================================
   Status-Panel - Erfolgs-/Abschlussmeldung (Bestell- und Angebotsbestaetigung)
   Neutral gehalten (keine Markenfarbe im CSS): die Faerbung kommt ueber
   text-primary/text-success im Markup, damit es theme-aware bleibt.
   ========================================================================== */

.status-panel {
    padding: 2.5rem 1rem;
    text-align: center;
    border: 1px solid #e9ecef;
    border-radius: 14px;
    background-color: #f6f8fb;
}

.status-panel__icon {
    font-size: 3rem;
    line-height: 1;
    margin-bottom: .75rem;
}

.status-panel__title {
    margin-bottom: .75rem;
}

/* ==========================================================================
   Touch-Ziele in Datentabellen und Dialogen
   Die Aktionsbuttons der .data-table sind btn-sm (~31px) - unter der 44px-
   Empfehlung, und sie stehen dicht nebeneinander (Uebernehmen direkt neben
   Loeschen). Der Modal-Close ist mit ~24px der kleinste Notausgang im Shop.
   Nur bei grobem Zeiger, damit die Maus-Optik unveraendert bleibt.
   ========================================================================== */

@media (pointer: coarse) {
    /* --cell--order gehoert zwingend dazu: dort stehen Mengenfeld und Absende-Button
       (Favoritenliste). Sie MUESSEN in derselben Zelle liegen wie ihr <form>, sind also
       nicht Teil der Aktionszelle - ohne diesen Selektor waeren sie auf dem Touchgeraet
       ~31px hoch, waehrend der Loeschen-Button daneben auf 44px waechst. Genau das laesst
       die Zeile mobil verrutschen. */
    .data-table__cell--actions .btn,
    .data-table__cell--actions .qty-stepper__btn,
    .data-table__cell--order .btn,
    .data-table__cell--order .qty-stepper__btn {
        min-height: 44px;
    }

    .modal-header .close {
        min-width: 44px;
        min-height: 44px;
    }

    /* "N weitere anzeigen" ist der einzige Weg zu den restlichen Positionen -
       als btn-sm waeren das ~31px. */
    .position-more .btn {
        min-height: 44px;
    }

    /* Trefferflaeche der Checkbox-Beschriftung ("Warenkorb komplett liefern") ist
       sonst ~24px hoch. Padding statt min-height, damit der Indikator mittig bleibt. */
    .checkout-card .custom-control-label {
        padding-top: .6rem;
        padding-bottom: .6rem;
    }

    .checkout-card .custom-control-label::before,
    .checkout-card .custom-control-label::after {
        top: 50%;
        transform: translateY(-50%);
    }
}

/* ==========================================================================
   Nachbesserungen Bestellabschluss / Adressdialog
   ========================================================================== */

/* .cart-notice ist align-items:center und fuer EINZEILER gedacht (Warenkorb-Freitexte,
   Schnellerfassungs-Hinweis). Bei mehrzeiligem Inhalt - etwa der Ferienliste einer
   Anschrift - zentriert sich das Icon gegen die Gesamthoehe und schwebt mittig im
   Nichts. Dieser Modifier setzt es an den Anfang. */
.cart-notice--block {
    align-items: flex-start;
}

/* Der AGB-Hinweis stand optisch gleichrangig neben dem generischen ERP-Marketingtext:
   beide .cart-summary__note mit .75rem in #6c757d. Fuer einen Text, mit dem der Nutzer
   die AGB akzeptiert, ist das zu leise. */
.cart-summary__note--legal {
    font-size: .8125rem;
    color: #495057;
}

.cart-summary__note--legal a {
    text-decoration: underline;
}

/* Der Chip auf den Bestaetigungsseiten traegt variablen, ERP-gepflegten Text
   (Bestell-/Angebotsnummer). .hero-chip ist white-space:nowrap - fuer den urspruenglichen
   Zweck (Artikelzaehler) richtig, hier reisst es auf 320px die Seite auf. */
.status-panel .hero-chip {
    white-space: normal;
    max-width: 100%;
}

/* Sprungziele unter dem sticky Header freihalten - 6rem, derselbe Wert wie bei den
   uebrigen Ankern (#assignedProducts/#portalPartnerGroup/#fastEntry weiter oben).
   #Contact: Hinweis "Ansprechpartner auswaehlen" aus dem Summen-Panel.
   #createWishList: "Neue Favoritenliste erstellen" aus Kopf und Leerzustand.
   #ShippingCondition ist bewusst NICHT dabei - darauf verlinkt nichts. */
#Contact,
#createWishList {
    scroll-margin-top: 6rem;
}

/* ==========================================================================
   Checkout-Sektionen (Cart/SubmitOrder)
   Jede Sektion ist EINE Karte, der Sektionskopf ist ihr card-header. Vorher
   standen Sektionsueberschrift (h5 + .hero-accent) und Karten getrennt
   uebereinander - Rahmen im Rahmen, und die Abstaende entstanden aus einer
   Mischung von mt-3/mb-3 statt aus einem Wert.
   ========================================================================== */

/* Schrittziffer im card-header. Form kommt von hier, die FARBE ueber
   bg-primary/text-white im Markup - damit bleibt sie theme-aware. */
.checkout-step__num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 1.6rem;
    height: 1.6rem;
    border-radius: 50%;
    font-size: .8125rem;
    font-weight: 600;
    line-height: 1;
}

/* Trenner innerhalb einer Sektion (Anschrift | Versandoptionen). */
.checkout-divider {
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid #e9ecef;
}

/* Der Kartenkopf ist zugleich der Collapse-Ausloeser (Sektion "Anmerkungen").
   Als <button> gebaut, damit er per Tastatur erreichbar ist - deshalb die
   Button-Defaults zuruecknehmen. Padding gleich dem card-header-Default, damit
   die Schrittziffern aller Sektionen auf einer vertikalen Linie stehen.
   Ohne cursor/hover liest sich eine ganze Kartenzeile als nicht interaktiv. */
.checkout-toggle {
    width: 100%;
    padding: .75rem 1.25rem;
    border: 0;
    background: none;
    text-align: left;
    cursor: pointer;
}

.checkout-toggle:hover {
    background-color: rgba(0, 0, 0, .03);
}

/* outline-offset MUSS negativ bleiben: .checkout-card traegt overflow:hidden,
   ein positiver Offset wuerde am Kartenrand abgeschnitten. */
.checkout-toggle:focus {
    outline: 2px solid currentColor;
    outline-offset: -2px;
}

/* Generische Chevron-Rotation fuer Bootstrap-Collapse.
   #6c757d statt #adb5bd: auf Kartenkopf-Grau ergaebe #adb5bd nur ~2,1:1 und
   verfehlt die 3:1-Anforderung fuer UI-Komponenten (WCAG 1.4.11) - der Chevron
   ist der einzige Hinweis auf die Klappbarkeit.
   HINWEIS: .common-features__chevron und .accessory-chevron machen exakt
   dasselbe unter anderem Namen. Diese Klasse ist als gemeinsames Ziel gedacht -
   die beiden koennen bei Gelegenheit darauf zusammengefuehrt werden, damit die
   Regel nicht ein drittes Mal existiert. */
.collapse-chevron {
    color: #6c757d;
    transition: transform .2s ease;
}

[aria-expanded="true"] > .collapse-chevron,
[aria-expanded="true"] .collapse-chevron {
    transform: rotate(180deg);
}

/* Datentabelle IN einer Karte (Positionsliste im Bestellabschluss).
   .data-table-wrap bringt eigenen Rahmen (1px/#e9ecef) und Radius (14px) mit - in einer
   Karte lagen damit zwei Rahmen mit unterschiedlichen Radien ineinander. Hier uebernimmt
   die Karte den Abschluss, der Wrap gibt Rahmen und Radien ab.
   Die Randzellen tragen eigene 13px-Radien (siehe Ecken-Block oben); ohne deren Ruecknahme
   blieben zwischen Zelle und Kartenrand weisse Ecken stehen. Den sauberen Beschnitt macht
   zusaetzlich das overflow:hidden von .checkout-card. */
.card-body > .data-table-wrap {
    border: 0;
    border-radius: 0;
}

.card-body > .data-table-wrap > .data-table > thead > tr:first-child > th:first-child,
.card-body > .data-table-wrap > .data-table > thead > tr:first-child > th:last-child,
.card-body > .data-table-wrap > .data-table > tbody > tr:last-child > td:first-child,
.card-body > .data-table-wrap > .data-table > tbody > tr:last-child > td:last-child {
    border-radius: 0;
}

/* ==========================================================================
   .data-table--dense  -  dichte Read-only-Liste (Positionen im Bestellabschluss
   und auf den Bestaetigungsseiten)

   Der Warenkorb braucht Platz: dort wird bearbeitet (Mengenfeld, Loeschen,
   Favoriten-Menue), und 80px-Bilder helfen beim Wiedererkennen. In der
   Bestaetigungsliste wird nur gelesen - dafuer sind 48px genug. Bei den im B2B
   ueblichen 30-50 Positionen ist der Unterschied entscheidend: mit der vollen
   Optik ist der Block auf dem Handy rund zehn Bildschirmhoehen hoch.

   Bewusst NICHT .data-table--compact: das setzt zusaetzlich font-size .875rem,
   die im Karten-Modus stehen bleibt (das Padding wird dort von der
   spezifischeren Zellregel ueberschrieben, die Schriftgroesse nicht). Die
   Positionen staenden mobil in 14px, im Warenkorb einen Schritt vorher in 16px.
   --dense laesst die Schriftgroesse deshalb in Ruhe.
   ========================================================================== */

.data-table--dense > thead > tr > th,
.data-table--dense > tbody > tr > td {
    padding: .45rem .5rem;
}

.data-table--dense .data-table__cell--media {
    width: 64px;
}

.data-table--dense .data-table__cell--media img {
    max-width: 48px;
}

@media (max-width: 767.98px) {
    /* Karten-Modus: kleineres Thumbnail (48 statt 80px) ... */
    .data-table-wrap--stack .data-table--dense > tbody > tr > td.data-table__cell--media {
        flex: 0 0 48px;
        width: 48px !important;
    }

    /* ... und Menge/Summe/Punkte nebeneinander statt untereinander. Jede Zahl
       belegte sonst eine eigene volle Zeile - drei Zeilen fuer drei kurze Werte. */
    .data-table-wrap--stack .data-table--dense > tbody > tr > td.data-table__num {
        flex: 1 1 40%;
    }
}

/* Umschalter unter der Positionsliste ("N weitere anzeigen"). Sitzt ausserhalb
   der Tabelle, soll aber als deren Fortsetzung lesbar sein. */
.position-more {
    padding: .25rem .5rem .5rem;
    text-align: center;
    border-top: 1px solid #edf0f2;
}

.position-more .btn-link {
    text-decoration: none;
}

.position-more .btn-link:hover {
    text-decoration: underline;
}

/* Karten-Modus INNERHALB einer Karte (Positionsliste in der Sektionskarte des
   Bestellabschlusses): --stack macht aus jeder Zeile eine eigene Karte mit Rahmen,
   Radius und Schatten. Steht die Tabelle selbst schon in einer Karte, ergibt das
   Karten in Karten - optisch unruhig und mit doppeltem Rahmen an jeder Zeile.
   Hier stattdessen flache Zeilen mit Trennlinie; das seitliche Padding uebernimmt
   die Zeile, weil der card-body p-0 traegt (auf dem Desktop soll die Tabelle bis
   an den Kartenrand laufen). */
@media (max-width: 767.98px) {
    .card-body > .data-table-wrap--stack > .data-table > tbody > tr {
        margin: 0;
        padding: .6rem .85rem;
        border: 0;
        border-bottom: 1px solid #edf0f2;
        border-radius: 0;
        box-shadow: none;
    }

    .card-body > .data-table-wrap--stack > .data-table > tbody > tr:last-child {
        border-bottom: 0;
    }
}

/* Sektionskarten des Bestellabschlusses.
   Bootstraps .card bringt border-radius .25rem (4px) mit - das Relaunch-System nutzt
   dagegen durchgehend 14px (.category-hero, .cart-summary, .data-table-wrap,
   .cart-notice, .status-panel). Ohne diesen Modifier stuenden auf einer Seite Panels
   mit 14px direkt neben Karten mit 4px.
   Bewusst KEIN globaler .card-Override: das wuerde jede Karte im Shop aendern.

   overflow:hidden laesst die Karte die eingebettete Positionstabelle sauber
   ausschneiden (sie laeuft im card-body p-0 bis an den Rand). Unbedenklich, weil in
   diesen Karten nur native <select> stecken - die rendert der Browser ausserhalb des
   Dokumentflusses. Bootstrap-Dropdowns duerfen hier NICHT hinein, die wuerden
   abgeschnitten. */
.checkout-card {
    border-radius: 14px;
    overflow: hidden;
}

/* Druckansicht der Positionsliste.
   Die Vorschau blendet alles ab der sechsten Position per .d-none aus. Auf einer
   ausgedruckten Auftragsbestaetigung waeren damit die meisten Positionen schlicht nicht
   vorhanden - bei einem verbindlichen Beleg nicht vertretbar. Im Druck deshalb alle
   Zeilen zeigen und den Umschalter weglassen.
   Diese Datei wird nach bootstrap.min.css geladen, die Regel gewinnt also gegen
   .d-none (gleiche Spezifitaet, spaeter im Stylesheet). */
@media print {
    .position-row--more {
        display: table-row !important;
    }

    .position-more {
        display: none !important;
    }
}

/* ==========================================================================
   Feinschliff Datentabelle IN einer Karte
   ========================================================================== */

/* Randzellen auf das Karten-Padding ziehen. Der card-header hat 1.25rem (20px),
   die Zellen von --dense nur .5rem (8px) - Kartentitel und erste Spalten-
   ueberschrift starteten dadurch 12px versetzt, ueber die volle Kartenhoehe
   sichtbar. */
.card-body > .data-table-wrap > .data-table > thead > tr > th:first-child,
.card-body > .data-table-wrap > .data-table > tbody > tr > td:first-child {
    padding-left: 1.25rem;
}

.card-body > .data-table-wrap > .data-table > thead > tr > th:last-child,
.card-body > .data-table-wrap > .data-table > tbody > tr > td:last-child {
    padding-right: 1.25rem;
}

/* Tabellenkopf und card-header tragen beide #f8f9fa - die Themes ueberschreiben
   .card-header entsprechend (Vomberg/Schneider/WEKU), und Theme-CSS laedt nach
   dieser Datei. Zwei gleich getoente Baender uebereinander, getrennt nur durch
   1px. In der Karte deshalb weiss; die Abgrenzung macht die 2px-Unterlinie. */
.card-body > .data-table-wrap > .data-table > thead > tr > th {
    background-color: #fff;
}

/* Leerzustand in der Karte: .data-table-empty bringt gestrichelten Rahmen und
   14px-Radius mit - beides lag exakt auf dem Kartenrahmen bzw. erzeugte runde
   Ecken mitten in der Karte. */
.card-body > .data-table-empty {
    border: 0;
    border-radius: 0;
    padding: 2rem 1.25rem;
}

/* Zugeklappte Sektion: ist der card-header das einzige sichtbare Kind, liegt
   seine border-bottom direkt auf der border-bottom der Karte - eine sichtbar
   doppelte, dunklere Linie. Betrifft "Anmerkungen" im Normalfall. */
.checkout-card > .card-header:last-child {
    border-bottom: 0;
}

/* Letztes Formularfeld: form-group traegt 1rem margin-bottom, dazu 1.25rem
   card-body-Padding = 36px unten gegen 20px oben. Bisher haing das an einem
   manuellen mb-0, das nur im Admin-Zweig gesetzt war. */
.checkout-card .card-body > form:last-child .form-group:last-child,
.checkout-card .card-body > .form-group:last-child {
    margin-bottom: 0;
}
